summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar xleroy <xleroy@fca1b0fc-160b-0410-b1d3-a4f43f01ea2e>2007-08-04 07:27:50 +0000
committerGravatar xleroy <xleroy@fca1b0fc-160b-0410-b1d3-a4f43f01ea2e>2007-08-04 07:27:50 +0000
commit355b4abcee015c3fae9ac5653c25259e104a886c (patch)
treecfdb5b17f36b815bb358699cf420f64eba9dfe25
parent22ff08b38616ceef336f5f974d4edc4d37d955e8 (diff)
Fusion des modifications faites sur les branches "tailcalls" et "smallstep".
En particulier: - Semantiques small-step depuis RTL jusqu'a PPC - Cminor independant du processeur - Ajout passes Selection et Reload - Ajout des langages intermediaires CminorSel et LTLin correspondants - Ajout des tailcalls depuis Cminor jusqu'a PPC git-svn-id: https://yquem.inria.fr/compcert/svn/compcert/trunk@384 fca1b0fc-160b-0410-b1d3-a4f43f01ea2e
-rw-r--r--.depend100
-rw-r--r--Makefile40
-rw-r--r--backend/Allocation.v382
-rw-r--r--backend/Allocproof.v1971
-rw-r--r--backend/Alloctyping.v516
-rw-r--r--backend/Bounds.v357
-rw-r--r--backend/CSE.v8
-rw-r--r--backend/CSEproof.v349
-rw-r--r--backend/Cminor.v333
-rw-r--r--backend/CminorSel.v296
-rw-r--r--backend/Coloring.v2
-rw-r--r--backend/Coloringproof.v1
-rw-r--r--backend/Constprop.v58
-rw-r--r--backend/Constpropproof.v609
-rw-r--r--backend/Conventions.v281
-rw-r--r--backend/LTL.v504
-rw-r--r--backend/LTLin.v255
-rw-r--r--backend/LTLintyping.v104
-rw-r--r--backend/LTLtyping.v160
-rw-r--r--backend/Linear.v243
-rw-r--r--backend/Linearize.v144
-rw-r--r--backend/Linearizeproof.v865
-rw-r--r--backend/Linearizetyping.v345
-rw-r--r--backend/Lineartyping.v208
-rw-r--r--backend/Locations.v2
-rw-r--r--backend/Mach.v256
-rw-r--r--backend/Machabstr.v512
-rw-r--r--backend/Machabstr2concr.v947
-rw-r--r--backend/Machabstr2mach.v1185
-rw-r--r--backend/Machconcr.v250
-rw-r--r--backend/Machtyping.v312
-rw-r--r--backend/Op.v257
-rw-r--r--backend/PPC.v96
-rw-r--r--backend/PPCgen.v30
-rw-r--r--backend/PPCgenproof.v1315
-rw-r--r--backend/PPCgenproof1.v58
-rw-r--r--backend/PPCgenretaddr.v176
-rw-r--r--backend/Parallelmove.v85
-rw-r--r--backend/RTL.v293
-rw-r--r--backend/RTLbigstep.v400
-rw-r--r--backend/RTLgen.v120
-rw-r--r--backend/RTLgenproof.v1584
-rw-r--r--backend/RTLgenproof1.v1367
-rw-r--r--backend/RTLgenspec.v1455
-rw-r--r--backend/RTLtyping.v356
-rw-r--r--backend/Registers.v7
-rw-r--r--backend/Reload.v211
-rw-r--r--backend/Reloadproof.v1230
-rw-r--r--backend/Reloadtyping.v309
-rw-r--r--backend/Selection.v (renamed from backend/Cmconstr.v)210
-rw-r--r--backend/Selectionproof.v (renamed from backend/Cmconstrproof.v)523
-rw-r--r--backend/Stacking.v88
-rw-r--r--backend/Stackingproof.v1585
-rw-r--r--backend/Stackingtyping.v121
-rw-r--r--backend/Tunneling.v56
-rw-r--r--backend/Tunnelingproof.v472
-rw-r--r--backend/Tunnelingtyping.v61
-rw-r--r--caml/CMlexer.mll3
-rw-r--r--caml/CMparser.mly194
-rw-r--r--caml/CMtypecheck.ml239
-rw-r--r--caml/Camlcoq.ml45
-rw-r--r--caml/Coloringaux.ml18
-rw-r--r--caml/Main2.ml8
-rw-r--r--caml/PrintPPC.ml6
-rw-r--r--caml/RTLgenaux.ml46
-rw-r--r--caml/RTLtypingaux.ml21
-rw-r--r--cfrontend/Cminorgen.v221
-rw-r--r--cfrontend/Cminorgenproof.v694
-rw-r--r--cfrontend/Csem.v3
-rw-r--r--cfrontend/Csharpminor.v150
-rw-r--r--cfrontend/Cshmgen.v276
-rw-r--r--cfrontend/Cshmgenproof1.v134
-rw-r--r--cfrontend/Cshmgenproof2.v103
-rw-r--r--cfrontend/Cshmgenproof3.v179
-rw-r--r--cfrontend/Csyntax.v11
-rw-r--r--common/AST.v219
-rw-r--r--common/Errors.v167
-rw-r--r--common/Events.v117
-rw-r--r--common/Globalenvs.v690
-rw-r--r--common/Main.v352
-rw-r--r--common/Mem.v3281
-rw-r--r--common/Smallstep.v460
-rw-r--r--common/Switch.v165
-rw-r--r--common/Values.v64
-rwxr-xr-xcoq2
-rw-r--r--doc/backend.html250
-rw-r--r--doc/coqdoc.css62
-rw-r--r--doc/index.html8561
-rwxr-xr-xdoc/removeproofs2
-rw-r--r--doc/style.css4
-rw-r--r--extraction/.depend370
-rw-r--r--extraction/Makefile26
-rwxr-xr-xextraction/convert1
-rw-r--r--extraction/extraction.v1
-rw-r--r--lib/Coqlib.v40
-rw-r--r--lib/Iteration.v64
-rw-r--r--lib/Parmov.v505
-rw-r--r--runtime/Makefile13
-rw-r--r--runtime/calloc.c13
-rw-r--r--runtime/stdio.c152
-rw-r--r--runtime/stdio.h67
-rw-r--r--test/c/Makefile9
-rw-r--r--test/c/knucleotide.c4
-rw-r--r--test/c/mandelbrot.c4
-rw-r--r--test/cminor/Makefile6
-rw-r--r--test/cminor/sha1.cmp2
-rw-r--r--test/cminor/switchtbl.cm16
-rw-r--r--test/harness/mainlists.c5
-rw-r--r--test/harness/mainswitchtbl.c11
109 files changed, 18742 insertions, 23374 deletions
diff --git a/.depend b/.depend
index 5262e32..d8ec3bd 100644
--- a/.depend
+++ b/.depend
@@ -6,64 +6,76 @@ lib/Iteration.vo: lib/Iteration.v lib/Coqlib.vo
lib/Integers.vo: lib/Integers.v lib/Coqlib.vo
lib/Floats.vo: lib/Floats.v lib/Coqlib.vo lib/Integers.vo
lib/Parmov.vo: lib/Parmov.v lib/Coqlib.vo
-common/AST.vo: common/AST.v lib/Coqlib.vo lib/Integers.vo lib/Floats.vo
+common/Errors.vo: common/Errors.v lib/Coqlib.vo
+common/AST.vo: common/AST.v lib/Coqlib.vo common/Errors.vo lib/Integers.vo lib/Floats.vo
common/Events.vo: common/Events.v lib/Coqlib.vo common/AST.vo lib/Integers.vo lib/Floats.vo common/Values.vo common/Mem.vo
-common/Globalenvs.vo: common/Globalenvs.v lib/Coqlib.vo lib/Maps.vo common/AST.vo lib/Integers.vo common/Values.vo common/Mem.vo
+common/Globalenvs.vo: common/Globalenvs.v lib/Coqlib.vo common/Errors.vo lib/Maps.vo common/AST.vo lib/Integers.vo common/Values.vo common/Mem.vo
common/Mem.vo: common/Mem.v lib/Coqlib.vo lib/Maps.vo common/AST.vo lib/Integers.vo lib/Floats.vo common/Values.vo
common/Values.vo: common/Values.v lib/Coqlib.vo common/AST.vo lib/Integers.vo lib/Floats.vo
-common/Main.vo: common/Main.v lib/Coqlib.vo lib/Maps.vo common/AST.vo common/Values.vo cfrontend/Csyntax.vo cfrontend/Csem.vo cfrontend/Csharpminor.vo backend/Cminor.vo backend/RTL.vo backend/LTL.vo backend/Linear.vo backend/Mach.vo backend/PPC.vo cfrontend/Cshmgen.vo cfrontend/Cminorgen.vo backend/RTLgen.vo backend/Constprop.vo backend/CSE.vo backend/Allocation.vo backend/Tunneling.vo backend/Linearize.vo backend/Stacking.vo backend/PPCgen.vo cfrontend/Ctyping.vo backend/RTLtyping.vo backend/LTLtyping.vo backend/Lineartyping.vo backend/Machtyping.vo cfrontend/Cshmgenproof3.vo cfrontend/Cminorgenproof.vo backend/RTLgenproof.vo backend/Constpropproof.vo backend/CSEproof.vo backend/Allocproof.vo backend/Alloctyping.vo backend/Tunnelingproof.vo backend/Tunnelingtyping.vo backend/Linearizeproof.vo backend/Linearizetyping.vo backend/Stackingproof.vo backend/Stackingtyping.vo backend/Machabstr2mach.vo backend/PPCgenproof.vo
+common/Smallstep.vo: common/Smallstep.v lib/Coqlib.vo common/AST.vo common/Events.vo common/Globalenvs.vo lib/Integers.vo
+common/Switch.vo: common/Switch.v lib/Coqlib.vo lib/Integers.vo
+common/Main.vo: common/Main.v lib/Coqlib.vo lib/Maps.vo common/Errors.vo common/AST.vo common/Values.vo common/Smallstep.vo cfrontend/Csyntax.vo cfrontend/Csem.vo cfrontend/Csharpminor.vo backend/Cminor.vo backend/CminorSel.vo backend/RTL.vo backend/LTL.vo backend/LTLin.vo backend/Linear.vo backend/Mach.vo backend/PPC.vo cfrontend/Cshmgen.vo cfrontend/Cminorgen.vo backend/Selection.vo backend/RTLgen.vo backend/Constprop.vo backend/CSE.vo backend/Allocation.vo backend/Tunneling.vo backend/Linearize.vo backend/Reload.vo backend/Stacking.vo backend/PPCgen.vo cfrontend/Ctyping.vo backend/RTLtyping.vo backend/LTLtyping.vo backend/LTLintyping.vo backend/Lineartyping.vo backend/Machtyping.vo cfrontend/Cshmgenproof3.vo cfrontend/Cminorgenproof.vo backend/Selectionproof.vo backend/RTLgenproof.vo backend/Constpropproof.vo backend/CSEproof.vo backend/Allocproof.vo backend/Alloctyping.vo backend/Tunnelingproof.vo backend/Tunnelingtyping.vo backend/Linearizeproof.vo backend/Linearizetyping.vo backend/Reloadproof.vo backend/Reloadtyping.vo backend/Stackingproof.vo backend/Stackingtyping.vo backend/Machabstr2concr.vo backend/PPCgenproof.vo
+backend/Cminor.vo: backend/Cminor.v lib/Coqlib.vo lib/Maps.vo common/AST.vo lib/Integers.vo lib/Floats.vo common/Events.vo common/Values.vo common/Mem.vo common/Globalenvs.vo common/Switch.vo
backend/Op.vo: backend/Op.v lib/Coqlib.vo common/AST.vo lib/Integers.vo lib/Floats.vo common/Values.vo common/Mem.vo common/Globalenvs.vo
-backend/Cminor.vo: backend/Cminor.v lib/Coqlib.vo lib/Maps.vo common/AST.vo lib/Integers.vo lib/Floats.vo common/Events.vo common/Values.vo common/Mem.vo backend/Op.vo common/Globalenvs.vo
-backend/Cmconstr.vo: backend/Cmconstr.v lib/Coqlib.vo lib/Maps.vo common/AST.vo lib/Integers.vo lib/Floats.vo common/Values.vo common/Mem.vo backend/Op.vo common/Globalenvs.vo backend/Cminor.vo
-backend/Cmconstrproof.vo: backend/Cmconstrproof.v lib/Coqlib.vo lib/Maps.vo common/AST.vo lib/Integers.vo lib/Floats.vo common/Values.vo common/Mem.vo common/Events.vo backend/Op.vo common/Globalenvs.vo backend/Cminor.vo backend/Cmconstr.vo
+backend/CminorSel.vo: backend/CminorSel.v lib/Coqlib.vo lib/Maps.vo common/AST.vo lib/Integers.vo lib/Floats.vo common/Events.vo common/Values.vo common/Mem.vo backend/Cminor.vo backend/Op.vo common/Globalenvs.vo common/Switch.vo
+backend/Selection.vo: backend/Selection.v lib/Coqlib.vo lib/Maps.vo common/AST.vo lib/Integers.vo lib/Floats.vo common/Values.vo common/Mem.vo common/Globalenvs.vo backend/Cminor.vo backend/Op.vo backend/CminorSel.vo
+backend/Selectionproof.vo: backend/Selectionproof.v lib/Coqlib.vo lib/Maps.vo common/AST.vo lib/Integers.vo lib/Floats.vo common/Values.vo common/Mem.vo common/Events.vo common/Globalenvs.vo backend/Cminor.vo backend/Op.vo backend/CminorSel.vo backend/Selection.vo
backend/Registers.vo: backend/Registers.v lib/Coqlib.vo common/AST.vo lib/Maps.vo lib/Ordered.vo
-backend/RTL.vo: backend/RTL.v lib/Coqlib.vo lib/Maps.vo common/AST.vo lib/Integers.vo common/Values.vo common/Events.vo common/Mem.vo common/Globalenvs.vo backend/Op.vo backend/Registers.vo
-backend/RTLgen.vo: backend/RTLgen.v lib/Coqlib.vo lib/Maps.vo common/AST.vo lib/Integers.vo common/Values.vo backend/Op.vo backend/Registers.vo backend/Cminor.vo backend/RTL.vo
-backend/RTLgenproof1.vo: backend/RTLgenproof1.v lib/Coqlib.vo lib/Maps.vo common/AST.vo lib/Integers.vo common/Values.vo common/Events.vo common/Mem.vo common/Globalenvs.vo backend/Op.vo backend/Registers.vo backend/Cminor.vo backend/RTL.vo backend/RTLgen.vo
-backend/RTLgenproof.vo: backend/RTLgenproof.v lib/Coqlib.vo lib/Maps.vo common/AST.vo lib/Integers.vo common/Values.vo common/Mem.vo common/Events.vo common/Globalenvs.vo backend/Op.vo backend/Registers.vo backend/Cminor.vo backend/RTL.vo backend/RTLgen.vo backend/RTLgenproof1.vo
-backend/RTLtyping.vo: backend/RTLtyping.v lib/Coqlib.vo lib/Maps.vo common/AST.vo backend/Op.vo backend/Registers.vo backend/RTL.vo backend/Conventions.vo common/Globalenvs.vo common/Values.vo common/Mem.vo lib/Integers.vo common/Events.vo
-backend/Kildall.vo: backend/Kildall.v lib/Coqlib.vo lib/Iteration.vo lib/Maps.vo lib/Lattice.vo
+backend/RTL.vo: backend/RTL.v lib/Coqlib.vo lib/Maps.vo common/AST.vo lib/Integers.vo common/Values.vo common/Events.vo common/Mem.vo common/Globalenvs.vo common/Smallstep.vo backend/Op.vo backend/Registers.vo
+backend/RTLgen.vo: backend/RTLgen.v lib/Coqlib.vo common/Errors.vo lib/Maps.vo common/AST.vo lib/Integers.vo common/Values.vo common/Switch.vo backend/Op.vo backend/Registers.vo backend/CminorSel.vo backend/RTL.vo
+backend/RTLgenspec.vo: backend/RTLgenspec.v lib/Coqlib.vo common/Errors.vo lib/Maps.vo common/AST.vo lib/Integers.vo common/Values.vo common/Events.vo common/Mem.vo common/Globalenvs.vo common/Switch.vo backend/Op.vo backend/Registers.vo backend/CminorSel.vo backend/RTL.vo backend/RTLgen.vo
+backend/RTLgenproof.vo: backend/RTLgenproof.v lib/Coqlib.vo lib/Maps.vo common/AST.vo lib/Integers.vo common/Values.vo common/Mem.vo common/Events.vo common/Smallstep.vo common/Globalenvs.vo common/Switch.vo backend/Registers.vo backend/Cminor.vo backend/Op.vo backend/CminorSel.vo backend/RTL.vo backend/RTLgen.vo backend/RTLgenspec.vo common/Errors.vo
+backend/RTLtyping.vo: backend/RTLtyping.v lib/Coqlib.vo common/Errors.vo lib/Maps.vo common/AST.vo backend/Op.vo backend/Registers.vo backend/RTL.vo backend/Conventions.vo common/Globalenvs.vo common/Values.vo common/Mem.vo lib/Integers.vo common/Events.vo common/Smallstep.vo
+backend/Kildall.vo: backend/Kildall.v lib/Coqlib.vo lib/Iteration.vo lib/Maps.vo lib/Lattice.vo lib/Ordered.vo
backend/Constprop.vo: backend/Constprop.v lib/Coqlib.vo lib/Maps.vo common/AST.vo lib/Integers.vo lib/Floats.vo common/Values.vo common/Globalenvs.vo backend/Op.vo backend/Registers.vo backend/RTL.vo lib/Lattice.vo backend/Kildall.vo
-backend/Constpropproof.vo: backend/Constpropproof.v lib/Coqlib.vo lib/Maps.vo common/AST.vo lib/Integers.vo lib/Floats.vo common/Values.vo common/Events.vo common/Mem.vo common/Globalenvs.vo backend/Op.vo backend/Registers.vo backend/RTL.vo lib/Lattice.vo backend/Kildall.vo backend/Constprop.vo
+backend/Constpropproof.vo: backend/Constpropproof.v lib/Coqlib.vo lib/Maps.vo common/AST.vo lib/Integers.vo lib/Floats.vo common/Values.vo common/Events.vo common/Mem.vo common/Globalenvs.vo common/Smallstep.vo backend/Op.vo backend/Registers.vo backend/RTL.vo lib/Lattice.vo backend/Kildall.vo backend/Constprop.vo
backend/CSE.vo: backend/CSE.v lib/Coqlib.vo lib/Maps.vo common/AST.vo lib/Integers.vo lib/Floats.vo common/Values.vo common/Mem.vo common/Globalenvs.vo backend/Op.vo backend/Registers.vo backend/RTL.vo backend/Kildall.vo
-backend/CSEproof.vo: backend/CSEproof.v lib/Coqlib.vo lib/Maps.vo common/AST.vo lib/Integers.vo lib/Floats.vo common/Values.vo common/Mem.vo common/Events.vo common/Globalenvs.vo backend/Op.vo backend/Registers.vo backend/RTL.vo backend/Kildall.vo backend/CSE.vo
+backend/CSEproof.vo: backend/CSEproof.v lib/Coqlib.vo lib/Maps.vo common/AST.vo lib/Integers.vo lib/Floats.vo common/Values.vo common/Mem.vo common/Events.vo common/Globalenvs.vo common/Smallstep.vo backend/Op.vo backend/Registers.vo backend/RTL.vo backend/Kildall.vo backend/CSE.vo
backend/Locations.vo: backend/Locations.v lib/Coqlib.vo lib/Maps.vo common/AST.vo common/Values.vo
backend/Conventions.vo: backend/Conventions.v lib/Coqlib.vo common/AST.vo backend/Locations.vo
-backend/LTL.vo: backend/LTL.v lib/Coqlib.vo lib/Maps.vo common/AST.vo lib/Integers.vo common/Values.vo common/Events.vo common/Mem.vo common/Globalenvs.vo backend/Op.vo backend/Locations.vo backend/Conventions.vo
+backend/LTL.vo: backend/LTL.v lib/Coqlib.vo lib/Maps.vo common/AST.vo lib/Integers.vo common/Values.vo common/Events.vo common/Mem.vo common/Globalenvs.vo common/Smallstep.vo backend/Op.vo backend/Locations.vo backend/Conventions.vo
backend/LTLtyping.vo: backend/LTLtyping.v lib/Coqlib.vo lib/Maps.vo common/AST.vo backend/Op.vo backend/RTL.vo backend/Locations.vo backend/LTL.vo backend/Conventions.vo
backend/InterfGraph.vo: backend/InterfGraph.v lib/Coqlib.vo lib/Maps.vo lib/Ordered.vo backend/Registers.vo backend/Locations.vo
backend/Coloring.vo: backend/Coloring.v lib/Coqlib.vo lib/Maps.vo common/AST.vo backend/Op.vo backend/Registers.vo backend/RTL.vo backend/RTLtyping.vo backend/Locations.vo backend/Conventions.vo backend/InterfGraph.vo
backend/Coloringproof.vo: backend/Coloringproof.v lib/Coqlib.vo lib/Maps.vo common/AST.vo backend/Op.vo backend/Registers.vo backend/RTL.vo backend/RTLtyping.vo backend/Locations.vo backend/Conventions.vo backend/InterfGraph.vo backend/Coloring.vo
-backend/Parallelmove.vo: backend/Parallelmove.v lib/Coqlib.vo lib/Parmov.vo common/Values.vo common/Events.vo common/AST.vo backend/Locations.vo backend/Conventions.vo
-backend/Allocation.vo: backend/Allocation.v lib/Coqlib.vo lib/Maps.vo lib/Lattice.vo common/AST.vo lib/Integers.vo common/Values.vo common/Globalenvs.vo backend/Op.vo backend/Registers.vo backend/RTL.vo backend/RTLtyping.vo backend/Kildall.vo backend/Locations.vo backend/Conventions.vo backend/Coloring.vo backend/Parallelmove.vo backend/LTL.vo
-backend/Allocproof.vo: backend/Allocproof.v lib/Coqlib.vo lib/Maps.vo common/AST.vo lib/Integers.vo common/Values.vo common/Mem.vo common/Events.vo common/Globalenvs.vo backend/Op.vo backend/Registers.vo backend/RTL.vo backend/RTLtyping.vo backend/Locations.vo backend/Conventions.vo backend/Coloring.vo backend/Coloringproof.vo backend/Parallelmove.vo backend/Allocation.vo backend/LTL.vo
-backend/Alloctyping.vo: backend/Alloctyping.v lib/Coqlib.vo lib/Maps.vo common/AST.vo backend/Op.vo backend/Registers.vo backend/RTL.vo backend/Locations.vo backend/LTL.vo backend/Coloring.vo backend/Coloringproof.vo backend/Allocation.vo backend/Allocproof.vo backend/RTLtyping.vo backend/LTLtyping.vo backend/Conventions.vo backend/Parallelmove.vo
+backend/Allocation.vo: backend/Allocation.v lib/Coqlib.vo common/Errors.vo lib/Maps.vo lib/Lattice.vo common/AST.vo lib/Integers.vo common/Values.vo common/Globalenvs.vo backend/Op.vo backend/Registers.vo backend/RTL.vo backend/RTLtyping.vo backend/Kildall.vo backend/Locations.vo backend/Conventions.vo backend/Coloring.vo backend/LTL.vo
+backend/Allocproof.vo: backend/Allocproof.v lib/Coqlib.vo common/Errors.vo lib/Maps.vo common/AST.vo lib/Integers.vo common/Values.vo common/Mem.vo common/Events.vo common/Smallstep.vo common/Globalenvs.vo backend/Op.vo backend/Registers.vo backend/RTL.vo backend/RTLtyping.vo backend/Locations.vo backend/Conventions.vo backend/Coloring.vo backend/Coloringproof.vo backend/Allocation.vo backend/LTL.vo
+backend/Alloctyping.vo: backend/Alloctyping.v lib/Coqlib.vo lib/Maps.vo common/Errors.vo common/AST.vo backend/Op.vo backend/Registers.vo backend/RTL.vo backend/Locations.vo backend/LTL.vo backend/Coloring.vo backend/Coloringproof.vo backend/Allocation.vo backend/Allocproof.vo backend/RTLtyping.vo backend/LTLtyping.vo backend/Conventions.vo
backend/Tunneling.vo: backend/Tunneling.v lib/Coqlib.vo lib/Maps.vo common/AST.vo common/Values.vo common/Globalenvs.vo backend/Op.vo backend/Locations.vo backend/LTL.vo
-backend/Tunnelingproof.vo: backend/Tunnelingproof.v lib/Coqlib.vo lib/Maps.vo common/AST.vo common/Values.vo common/Mem.vo common/Events.vo common/Globalenvs.vo backend/Op.vo backend/Locations.vo backend/LTL.vo backend/Tunneling.vo
-backend/Tunnelingtyping.vo: backend/Tunnelingtyping.v lib/Coqlib.vo lib/Maps.vo common/AST.vo common/Values.vo common/Mem.vo common/Globalenvs.vo backend/Op.vo backend/Locations.vo backend/LTL.vo backend/LTLtyping.vo backend/Tunneling.vo
-backend/Linear.vo: backend/Linear.v lib/Coqlib.vo lib/Maps.vo common/AST.vo lib/Integers.vo common/Values.vo common/Mem.vo common/Events.vo common/Globalenvs.vo backend/Op.vo backend/Locations.vo backend/LTL.vo backend/Conventions.vo
+backend/Tunnelingproof.vo: backend/Tunnelingproof.v lib/Coqlib.vo lib/Maps.vo common/AST.vo common/Values.vo common/Mem.vo common/Events.vo common/Globalenvs.vo common/Smallstep.vo backend/Op.vo backend/Locations.vo backend/LTL.vo backend/Tunneling.vo
+backend/Tunnelingtyping.vo: backend/Tunnelingtyping.v lib/Coqlib.vo lib/Maps.vo common/AST.vo common/Values.vo common/Mem.vo common/Globalenvs.vo backend/Op.vo backend/Locations.vo backend/LTL.vo backend/LTLtyping.vo backend/Tunneling.vo backend/Tunnelingproof.vo
+backend/LTLin.vo: backend/LTLin.v lib/Coqlib.vo lib/Maps.vo common/AST.vo lib/Integers.vo common/Values.vo common/Mem.vo common/Events.vo common/Globalenvs.vo common/Smallstep.vo backend/Op.vo backend/Locations.vo backend/LTL.vo backend/Conventions.vo
+backend/LTLintyping.vo: backend/LTLintyping.v lib/Coqlib.vo lib/Maps.vo common/AST.vo backend/Op.vo backend/RTL.vo backend/Locations.vo backend/LTLin.vo backend/Conventions.vo
+backend/Linearize.vo: backend/Linearize.v lib/Coqlib.vo lib/Maps.vo common/AST.vo common/Values.vo common/Globalenvs.vo backend/Op.vo backend/Locations.vo backend/LTL.vo backend/LTLin.vo backend/Kildall.vo lib/Lattice.vo
+backend/Linearizeproof.vo: backend/Linearizeproof.v lib/Coqlib.vo lib/Maps.vo common/AST.vo lib/Integers.vo common/Values.vo common/Mem.vo common/Events.vo common/Globalenvs.vo common/Smallstep.vo backend/Op.vo backend/Locations.vo backend/LTL.vo backend/LTLtyping.vo backend/LTLin.vo backend/Linearize.vo lib/Lattice.vo
+backend/Linearizetyping.vo: backend/Linearizetyping.v lib/Coqlib.vo lib/Maps.vo common/AST.vo backend/Op.vo backend/Locations.vo backend/LTL.vo backend/LTLtyping.vo backend/LTLin.vo backend/Linearize.vo backend/LTLintyping.vo backend/Conventions.vo
+backend/Linear.vo: backend/Linear.v lib/Coqlib.vo lib/Maps.vo common/AST.vo lib/Integers.vo common/Values.vo common/Mem.vo common/Events.vo common/Globalenvs.vo common/Smallstep.vo backend/Op.vo backend/Locations.vo backend/LTL.vo backend/Conventions.vo
backend/Lineartyping.vo: backend/Lineartyping.v lib/Coqlib.vo lib/Maps.vo common/AST.vo backend/Op.vo backend/RTL.vo backend/Locations.vo backend/Linear.vo backend/Conventions.vo
-backend/Linearize.vo: backend/Linearize.v lib/Coqlib.vo lib/Maps.vo common/AST.vo common/Values.vo common/Globalenvs.vo backend/Op.vo backend/Locations.vo backend/LTL.vo backend/Linear.vo backend/Kildall.vo lib/Lattice.vo
-backend/Linearizeproof.vo: backend/Linearizeproof.v lib/Coqlib.vo lib/Maps.vo common/AST.vo lib/Integers.vo common/Values.vo common/Mem.vo common/Events.vo common/Globalenvs.vo backend/Op.vo backend/Locations.vo backend/LTL.vo backend/Linear.vo backend/Linearize.vo lib/Lattice.vo
-backend/Linearizetyping.vo: backend/Linearizetyping.v lib/Coqlib.vo lib/Maps.vo common/AST.vo backend/Op.vo backend/Locations.vo backend/LTL.vo backend/Linear.vo backend/Linearize.vo backend/LTLtyping.vo backend/Lineartyping.vo backend/Conventions.vo
-backend/Mach.vo: backend/Mach.v lib/Coqlib.vo lib/Maps.vo common/AST.vo lib/Integers.vo common/Values.vo common/Mem.vo common/Events.vo common/Globalenvs.vo backend/Op.vo backend/Locations.vo backend/Conventions.vo
-backend/Machabstr.vo: backend/Machabstr.v lib/Coqlib.vo lib/Maps.vo common/AST.vo common/Mem.vo lib/Integers.vo common/Values.vo common/Events.vo common/Globalenvs.vo backend/Op.vo backend/Locations.vo backend/Conventions.vo backend/Mach.vo
+backend/Parallelmove.vo: backend/Parallelmove.v lib/Coqlib.vo lib/Parmov.vo common/Values.vo common/Events.vo common/AST.vo backend/Locations.vo backend/Conventions.vo
+backend/Reload.vo: backend/Reload.v lib/Coqlib.vo lib/Maps.vo common/AST.vo lib/Integers.vo common/Values.vo common/Globalenvs.vo backend/Op.vo backend/Locations.vo backend/LTLin.vo backend/Conventions.vo backend/Parallelmove.vo backend/Linear.vo
+backend/Reloadproof.vo: backend/Reloadproof.v lib/Coqlib.vo lib/Maps.vo common/AST.vo lib/Integers.vo common/Values.vo common/Mem.vo common/Events.vo common/Globalenvs.vo common/Smallstep.vo backend/Op.vo backend/Locations.vo backend/Conventions.vo backend/Allocproof.vo backend/LTLin.vo backend/LTLintyping.vo backend/Linear.vo backend/Parallelmove.vo backend/Reload.vo
+backend/Reloadtyping.vo: backend/Reloadtyping.v lib/Coqlib.vo lib/Maps.vo common/AST.vo backend/Op.vo backend/Locations.vo backend/LTLin.vo backend/LTLintyping.vo backend/Linear.vo backend/Lineartyping.vo backend/Conventions.vo backend/Parallelmove.vo backend/Reload.vo backend/Reloadproof.vo
+backend/Mach.vo: backend/Mach.v lib/Coqlib.vo lib/Maps.vo common/AST.vo lib/Integers.vo common/Values.vo common/Mem.vo common/Events.vo common/Globalenvs.vo backend/Op.vo backend/Locations.vo
+backend/Machabstr.vo: backend/Machabstr.v lib/Coqlib.vo lib/Maps.vo common/AST.vo common/Mem.vo lib/Integers.vo common/Values.vo common/Events.vo common/Globalenvs.vo common/Smallstep.vo backend/Op.vo backend/Locations.vo backend/Conventions.vo backend/Mach.vo
backend/Machtyping.vo: backend/Machtyping.v lib/Coqlib.vo lib/Maps.vo common/AST.vo common/Mem.vo lib/Integers.vo common/Values.vo common/Events.vo common/Globalenvs.vo backend/Op.vo backend/Locations.vo backend/Conventions.vo backend/Mach.vo backend/Machabstr.vo
-backend/Stacking.vo: backend/Stacking.v lib/Coqlib.vo lib/Maps.vo common/AST.vo lib/Integers.vo backend/Op.vo backend/RTL.vo backend/Locations.vo backend/Linear.vo backend/Lineartyping.vo backend/Mach.vo backend/Conventions.vo
-backend/Stackingproof.vo: backend/Stackingproof.v lib/Coqlib.vo lib/Maps.vo common/AST.vo lib/Integers.vo common/Values.vo backend/Op.vo common/Mem.vo common/Events.vo common/Globalenvs.vo backend/Locations.vo backend/Mach.vo backend/Machabstr.vo backend/Linear.vo backend/Lineartyping.vo backend/Conventions.vo backend/Stacking.vo
-backend/Stackingtyping.vo: backend/Stackingtyping.v lib/Coqlib.vo lib/Maps.vo lib/Integers.vo common/AST.vo backend/Op.vo backend/Locations.vo backend/Conventions.vo backend/Linear.vo backend/Lineartyping.vo backend/Mach.vo backend/Machtyping.vo backend/Stacking.vo backend/Stackingproof.vo
-backend/Machabstr2mach.vo: backend/Machabstr2mach.v lib/Coqlib.vo lib/Maps.vo common/AST.vo lib/Integers.vo common/Values.vo common/Mem.vo common/Events.vo common/Globalenvs.vo backend/Op.vo backend/Locations.vo backend/Machabstr.vo backend/Mach.vo backend/Machtyping.vo backend/Stackingproof.vo
-backend/PPC.vo: backend/PPC.v lib/Coqlib.vo lib/Maps.vo common/AST.vo lib/Integers.vo lib/Floats.vo common/Values.vo common/Mem.vo common/Events.vo common/Globalenvs.vo
-backend/PPCgen.vo: backend/PPCgen.v lib/Coqlib.vo lib/Maps.vo common/AST.vo lib/Integers.vo lib/Floats.vo common/Values.vo common/Mem.vo common/Globalenvs.vo backend/Op.vo backend/Locations.vo backend/Mach.vo backend/PPC.vo
-backend/PPCgenproof1.vo: backend/PPCgenproof1.v lib/Coqlib.vo lib/Maps.vo common/AST.vo lib/Integers.vo lib/Floats.vo common/Values.vo common/Mem.vo common/Globalenvs.vo backend/Op.vo backend/Locations.vo backend/Mach.vo backend/Machtyping.vo backend/PPC.vo backend/PPCgen.vo backend/Conventions.vo
-backend/PPCgenproof.vo: backend/PPCgenproof.v lib/Coqlib.vo lib/Maps.vo common/AST.vo lib/Integers.vo lib/Floats.vo common/Values.vo common/Mem.vo common/Events.vo common/Globalenvs.vo backend/Op.vo backend/Locations.vo backend/Mach.vo backend/Machtyping.vo backend/PPC.vo backend/PPCgen.vo backend/PPCgenproof1.vo
-cfrontend/Csyntax.vo: cfrontend/Csyntax.v lib/Coqlib.vo lib/Integers.vo lib/Floats.vo common/AST.vo
-cfrontend/Csem.vo: cfrontend/Csem.v lib/Coqlib.vo lib/Maps.vo lib/Integers.vo lib/Floats.vo common/Values.vo common/AST.vo common/Mem.vo common/Events.vo common/Globalenvs.vo cfrontend/Csyntax.vo
+backend/Bounds.vo: backend/Bounds.v lib/Coqlib.vo lib/Maps.vo common/AST.vo backend/Op.vo backend/Locations.vo backend/Linear.vo backend/Lineartyping.vo backend/Conventions.vo
+backend/Stacking.vo: backend/Stacking.v lib/Coqlib.vo lib/Maps.vo common/Errors.vo common/AST.vo lib/Integers.vo backend/Op.vo backend/RTL.vo backend/Locations.vo backend/Linear.vo backend/Bounds.vo backend/Mach.vo backend/Conventions.vo
+backend/Stackingproof.vo: backend/Stackingproof.v lib/Coqlib.vo lib/Maps.vo common/Errors.vo common/AST.vo lib/Integers.vo common/Values.vo backend/Op.vo common/Mem.vo common/Events.vo common/Globalenvs.vo common/Smallstep.vo backend/Locations.vo backend/Linear.vo backend/Lineartyping.vo backend/Mach.vo backend/Machabstr.vo backend/Bounds.vo backend/Conventions.vo backend/Stacking.vo
+backend/Stackingtyping.vo: backend/Stackingtyping.v lib/Coqlib.vo lib/Maps.vo common/Errors.vo lib/Integers.vo common/AST.vo backend/Op.vo backend/Locations.vo backend/Conventions.vo backend/Linear.vo backend/Lineartyping.vo backend/Mach.vo backend/Machtyping.vo backend/Bounds.vo backend/Stacking.vo backend/Stackingproof.vo
+backend/Machconcr.vo: backend/Machconcr.v lib/Coqlib.vo lib/Maps.vo common/AST.vo lib/Integers.vo common/Values.vo common/Mem.vo common/Events.vo common/Globalenvs.vo common/Smallstep.vo backend/Op.vo backend/Locations.vo backend/Conventions.vo backend/Mach.vo backend/PPCgenretaddr.vo
+backend/Machabstr2concr.vo: backend/Machabstr2concr.v lib/Coqlib.vo lib/Maps.vo common/AST.vo lib/Integers.vo common/Values.vo common/Mem.vo common/Events.vo common/Globalenvs.vo common/Smallstep.vo backend/Op.vo backend/Locations.vo backend/Mach.vo backend/Machtyping.vo backend/Machabstr.vo backend/Machconcr.vo backend/Stackingproof.vo backend/PPCgenretaddr.vo
+backend/PPC.vo: backend/PPC.v lib/Coqlib.vo lib/Maps.vo common/AST.vo lib/Integers.vo lib/Floats.vo common/Values.vo common/Mem.vo common/Events.vo common/Globalenvs.vo common/Smallstep.vo
+backend/PPCgen.vo: backend/PPCgen.v lib/Coqlib.vo lib/Maps.vo common/Errors.vo common/AST.vo lib/Integers.vo lib/Floats.vo common/Values.vo common/Mem.vo common/Globalenvs.vo backend/Op.vo backend/Locations.vo backend/Mach.vo backend/PPC.vo
+backend/PPCgenretaddr.vo: backend/PPCgenretaddr.v lib/Coqlib.vo lib/Maps.vo common/AST.vo lib/Integers.vo lib/Floats.vo common/Values.vo common/Mem.vo common/Globalenvs.vo backend/Op.vo backend/Locations.vo backend/Mach.vo backend/PPC.vo backend/PPCgen.vo
+backend/PPCgenproof1.vo: backend/PPCgenproof1.v lib/Coqlib.vo lib/Maps.vo common/AST.vo lib/Integers.vo lib/Floats.vo common/Values.vo common/Mem.vo common/Globalenvs.vo backend/Op.vo backend/Locations.vo backend/Mach.vo backend/Machconcr.vo backend/Machtyping.vo backend/PPC.vo backend/PPCgen.vo backend/Conventions.vo
+backend/PPCgenproof.vo: backend/PPCgenproof.v lib/Coqlib.vo lib/Maps.vo common/Errors.vo common/AST.vo lib/Integers.vo lib/Floats.vo common/Values.vo common/Mem.vo common/Events.vo common/Globalenvs.vo common/Smallstep.vo backend/Op.vo backend/Locations.vo backend/Mach.vo backend/Machconcr.vo backend/Machtyping.vo backend/PPC.vo backend/PPCgen.vo backend/PPCgenretaddr.vo backend/PPCgenproof1.vo
+cfrontend/Csyntax.vo: cfrontend/Csyntax.v lib/Coqlib.vo common/Errors.vo lib/Integers.vo lib/Floats.vo common/AST.vo
+cfrontend/Csem.vo: cfrontend/Csem.v lib/Coqlib.vo common/Errors.vo lib/Maps.vo lib/Integers.vo lib/Floats.vo common/Values.vo common/AST.vo common/Mem.vo common/Events.vo common/Globalenvs.vo cfrontend/Csyntax.vo
cfrontend/Ctyping.vo: cfrontend/Ctyping.v lib/Coqlib.vo lib/Maps.vo common/AST.vo cfrontend/Csyntax.vo
-cfrontend/Cshmgen.vo: cfrontend/Cshmgen.v lib/Coqlib.vo lib/Integers.vo lib/Floats.vo common/AST.vo cfrontend/Csyntax.vo cfrontend/Csharpminor.vo
-cfrontend/Cshmgenproof1.vo: cfrontend/Cshmgenproof1.v lib/Coqlib.vo lib/Maps.vo lib/Integers.vo lib/Floats.vo common/AST.vo common/Values.vo common/Events.vo common/Mem.vo common/Globalenvs.vo cfrontend/Csyntax.vo cfrontend/Csem.vo cfrontend/Ctyping.vo cfrontend/Csharpminor.vo cfrontend/Cshmgen.vo
-cfrontend/Cshmgenproof2.vo: cfrontend/Cshmgenproof2.v lib/Coqlib.vo lib/Maps.vo lib/Integers.vo lib/Floats.vo common/AST.vo common/Values.vo common/Events.vo common/Mem.vo common/Globalenvs.vo cfrontend/Csyntax.vo cfrontend/Csem.vo cfrontend/Ctyping.vo cfrontend/Csharpminor.vo cfrontend/Cshmgen.vo cfrontend/Cshmgenproof1.vo
-cfrontend/Cshmgenproof3.vo: cfrontend/Cshmgenproof3.v lib/Coqlib.vo lib/Maps.vo lib/Integers.vo lib/Floats.vo common/AST.vo common/Values.vo common/Events.vo common/Mem.vo common/Globalenvs.vo cfrontend/Csyntax.vo cfrontend/Csem.vo cfrontend/Ctyping.vo cfrontend/Csharpminor.vo cfrontend/Cshmgen.vo cfrontend/Cshmgenproof1.vo cfrontend/Cshmgenproof2.vo
-cfrontend/Csharpminor.vo: cfrontend/Csharpminor.v lib/Coqlib.vo lib/Maps.vo common/AST.vo lib/Integers.vo lib/Floats.vo common/Values.vo common/Mem.vo common/Events.vo common/Globalenvs.vo
-cfrontend/Cminorgen.vo: cfrontend/Cminorgen.v lib/Coqlib.vo lib/Maps.vo lib/Ordered.vo common/AST.vo lib/Integers.vo common/Mem.vo cfrontend/Csharpminor.vo backend/Op.vo backend/Cminor.vo backend/Cmconstr.vo
-cfrontend/Cminorgenproof.vo: cfrontend/Cminorgenproof.v lib/Coqlib.vo lib/Maps.vo common/AST.vo lib/Integers.vo lib/Floats.vo common/Values.vo common/Mem.vo common/Events.vo common/Globalenvs.vo cfrontend/Csharpminor.vo backend/Op.vo backend/Cminor.vo backend/Cmconstr.vo cfrontend/Cminorgen.vo backend/Cmconstrproof.vo
+cfrontend/Cshmgen.vo: cfrontend/Cshmgen.v lib/Coqlib.vo common/Errors.vo lib/Integers.vo lib/Floats.vo common/AST.vo cfrontend/Csyntax.vo backend/Cminor.vo cfrontend/Csharpminor.vo
+cfrontend/Cshmgenproof1.vo: cfrontend/Cshmgenproof1.v lib/Coqlib.vo common/Errors.vo lib/Maps.vo lib/Integers.vo lib/Floats.vo common/AST.vo common/Values.vo common/Events.vo common/Mem.vo common/Globalenvs.vo cfrontend/Csyntax.vo cfrontend/Csem.vo cfrontend/Ctyping.vo backend/Cminor.vo cfrontend/Csharpminor.vo cfrontend/Cshmgen.vo
+cfrontend/Cshmgenproof2.vo: cfrontend/Cshmgenproof2.v lib/Coqlib.vo common/Errors.vo lib/Maps.vo lib/Integers.vo lib/Floats.vo common/AST.vo common/Values.vo common/Events.vo common/Mem.vo common/Globalenvs.vo cfrontend/Csyntax.vo cfrontend/Csem.vo cfrontend/Ctyping.vo backend/Cminor.vo cfrontend/Csharpminor.vo cfrontend/Cshmgen.vo cfrontend/Cshmgenproof1.vo
+cfrontend/Cshmgenproof3.vo: cfrontend/Cshmgenproof3.v lib/Coqlib.vo common/Errors.vo lib/Maps.vo lib/Integers.vo lib/Floats.vo common/AST.vo common/Values.vo common/Events.vo common/Mem.vo common/Globalenvs.vo cfrontend/Csyntax.vo cfrontend/Csem.vo cfrontend/Ctyping.vo backend/Cminor.vo cfrontend/Csharpminor.vo cfrontend/Cshmgen.vo cfrontend/Cshmgenproof1.vo cfrontend/Cshmgenproof2.vo
+cfrontend/Csharpminor.vo: cfrontend/Csharpminor.v lib/Coqlib.vo lib/Maps.vo common/AST.vo lib/Integers.vo lib/Floats.vo common/Values.vo common/Mem.vo common/Events.vo common/Globalenvs.vo backend/Cminor.vo
+cfrontend/Cminorgen.vo: cfrontend/Cminorgen.v lib/Coqlib.vo common/Errors.vo lib/Maps.vo lib/Ordered.vo common/AST.vo lib/Integers.vo common/Mem.vo cfrontend/Csharpminor.vo backend/Op.vo backend/Cminor.vo
+cfrontend/Cminorgenproof.vo: cfrontend/Cminorgenproof.v lib/Coqlib.vo common/Errors.vo lib/Maps.vo common/AST.vo lib/Integers.vo lib/Floats.vo common/Values.vo common/Mem.vo common/Events.vo common/Globalenvs.vo cfrontend/Csharpminor.vo backend/Cminor.vo cfrontend/Cminorgen.vo
diff --git a/Makefile b/Makefile
index 00b0000..bea28ac 100644
--- a/Makefile
+++ b/Makefile
@@ -12,30 +12,32 @@ LIB=Coqlib.v Maps.v Lattice.v Ordered.v \
# Files in common/
-COMMON=AST.v Events.v Globalenvs.v Mem.v Values.v Main.v
+COMMON=Errors.v AST.v Events.v Globalenvs.v Mem.v Values.v \
+ Smallstep.v Switch.v Main.v
# Files in backend/
BACKEND=\
- Op.v Cminor.v \
- Cmconstr.v Cmconstrproof.v \
+ Cminor.v Op.v CminorSel.v \
+ Selection.v Selectionproof.v \
Registers.v RTL.v \
- RTLgen.v RTLgenproof1.v RTLgenproof.v \
+ RTLgen.v RTLgenspec.v RTLgenproof.v \
RTLtyping.v \
Kildall.v \
Constprop.v Constpropproof.v \
CSE.v CSEproof.v \
Locations.v Conventions.v LTL.v LTLtyping.v \
InterfGraph.v Coloring.v Coloringproof.v \
- Parallelmove.v Allocation.v \
- Allocproof.v Alloctyping.v \
+ Allocation.v Allocproof.v Alloctyping.v \
Tunneling.v Tunnelingproof.v Tunnelingtyping.v \
- Linear.v Lineartyping.v \
+ LTLin.v LTLintyping.v \
Linearize.v Linearizeproof.v Linearizetyping.v \
+ Linear.v Lineartyping.v \
+ Parallelmove.v Reload.v Reloadproof.v Reloadtyping.v \
Mach.v Machabstr.v Machtyping.v \
- Stacking.v Stackingproof.v Stackingtyping.v \
- Machabstr2mach.v \
- PPC.v PPCgen.v PPCgenproof1.v PPCgenproof.v
+ Bounds.v Stacking.v Stackingproof.v Stackingtyping.v \
+ Machconcr.v Machabstr2concr.v \
+ PPC.v PPCgen.v PPCgenretaddr.v PPCgenproof1.v PPCgenproof.v
# Files in cfrontend/
@@ -47,7 +49,7 @@ CFRONTEND=Csyntax.v Csem.v Ctyping.v Cshmgen.v \
FILES=$(LIB:%=lib/%) $(COMMON:%=common/%) $(BACKEND:%=backend/%) $(CFRONTEND:%=cfrontend/%)
-FLATFILES=$(LIB) $(BACKEND) $(CFRONTEND)
+FLATFILES=$(LIB) $(COMMON) $(BACKEND) $(CFRONTEND)
proof: $(FILES:.v=.vo)
@@ -65,24 +67,30 @@ cil:
$(MAKE) -C cil
documentation:
- $(COQDOC) --html -d doc $(FLATFILES:%.v=--glob-from doc/%.glob) $(FILES)
- doc/removeproofs doc/lib.*.html doc/backend.*.html
+ @ln -f $(FILES) doc/
+ @mkdir -p doc/html
+ cd doc; $(COQDOC) --html -d html \
+ $(FLATFILES:%.v=--glob-from %.glob) $(FLATFILES)
+ @cd doc; rm -f $(FLATFILES)
+ cp doc/coqdoc.css doc/html/coqdoc.css
+ doc/removeproofs doc/html/*.html
latexdoc:
- $(COQDOC) --latex -o doc/doc.tex -g $(FILES)
+ cd doc; $(COQDOC) --latex -o doc/doc.tex -g $(FILES)
.SUFFIXES: .v .vo
.v.vo:
@rm -f doc/glob/$(*F).glob
- $(COQC) -dump-glob doc/$(*F).glob $*.v
+ @echo "COQC $*.v"
+ @$(COQC) -dump-glob doc/$(*F).glob $*.v
depend:
$(COQDEP) $(FILES) > .depend
clean:
rm -f */*.vo *~ */*~
- rm -f doc/lib.*.html doc/backend.*.html doc/*.glob
+ rm -rf doc/html doc/*.glob
$(MAKE) -C extraction clean
$(MAKE) -C test/cminor clean
diff --git a/backend/Allocation.v b/backend/Allocation.v
index 74c85cf..eab5233 100644
--- a/backend/Allocation.v
+++ b/backend/Allocation.v
@@ -1,7 +1,7 @@
-(** Register allocation, spilling, reloading and explicitation of
- calling conventions. *)
+(** Register allocation. *)
Require Import Coqlib.
+Require Import Errors.
Require Import Maps.
Require Import Lattice.
Require Import AST.
@@ -16,15 +16,14 @@ Require Import Kildall.
Require Import Locations.
Require Import Conventions.
Require Import Coloring.
-Require Import Parallelmove.
(** * Liveness analysis over RTL *)
(** A register [r] is live at a point [p] if there exists a path
- from [p] to some instruction that uses [r] as argument,
- and [r] is not redefined along this path.
- Liveness can be computed by a backward dataflow analysis.
- The analysis operates over sets of (live) pseudo-registers. *)
+ from [p] to some instruction that uses [r] as argument,
+ and [r] is not redefined along this path.
+ Liveness can be computed by a backward dataflow analysis.
+ The analysis operates over sets of (live) pseudo-registers. *)
Notation reg_live := Regset.add.
Notation reg_dead := Regset.remove.
@@ -50,25 +49,25 @@ Fixpoint reg_list_dead
end.
(** Here is the transfer function for the dataflow analysis.
- Since this is a backward dataflow analysis, it takes as argument
- the abstract register set ``after'' the given instruction,
- i.e. the registers that are live after; and it returns as result
- the abstract register set ``before'' the given instruction,
- i.e. the registers that must be live before.
- The general relation between ``live before'' and ``live after''
- an instruction is that a register is live before if either
- it is one of the arguments of the instruction, or it is not the result
- of the instruction and it is live after.
- However, if the result of a side-effect-free instruction is not
- live ``after'', the whole instruction will be removed later
- (since it computes a useless result), thus its arguments need not
- be live ``before''. *)
+ Since this is a backward dataflow analysis, it takes as argument
+ the abstract register set ``after'' the given instruction,
+ i.e. the registers that are live after; and it returns as result
+ the abstract register set ``before'' the given instruction,
+ i.e. the registers that must be live before.
+ The general relation between ``live before'' and ``live after''
+ an instruction is that a register is live before if either
+ it is one of the arguments of the instruction, or it is not the result
+ of the instruction and it is live after.
+ However, if the result of a side-effect-free instruction is not
+ live ``after'', the whole instruction will be removed later
+ (since it computes a useless result), thus its arguments need not
+ be live ``before''. *)
Definition transfer
(f: RTL.function) (pc: node) (after: Regset.t) : Regset.t :=
match f.(fn_code)!pc with
| None =>
- after
+ Regset.empty
| Some i =>
match i with
| Inop s =>
@@ -88,18 +87,20 @@ Definition transfer
| Icall sig ros args res s =>
reg_list_live args
(reg_sum_live ros (reg_dead res after))
+ | Itailcall sig ros args =>
+ reg_list_live args (reg_sum_live ros Regset.empty)
| Ialloc arg res s =>
reg_live arg (reg_dead res after)
| Icond cond args ifso ifnot =>
reg_list_live args after
| Ireturn optarg =>
- reg_option_live optarg after
+ reg_option_live optarg Regset.empty
end
end.
(** The liveness analysis is then obtained by instantiating the
- general framework for backward dataflow analysis provided by
- module [Kildall]. *)
+ general framework for backward dataflow analysis provided by
+ module [Kildall]. *)
Module RegsetLat := LFSet(Regset).
Module DS := Backward_Dataflow_Solver(RegsetLat)(NodeSetBackward).
@@ -107,315 +108,108 @@ Module DS := Backward_Dataflow_Solver(RegsetLat)(NodeSetBackward).
Definition analyze (f: RTL.function): option (PMap.t Regset.t) :=
DS.fixpoint (successors f) f.(fn_nextpc) (transfer f) nil.
-(** * Spilling and reloading *)
-
-(** LTL operations, like those of the target processor, operate only
- over machine registers, but not over stack slots. Consider
- the RTL instruction
-<<
- r1 <- Iop(Oadd, r1 :: r2 :: nil)
->>
- and assume that [r1] and [r2] are assigned to stack locations [S s1]
- and [S s2], respectively. The translated LTL code must load these
- stack locations into temporary integer registers (this is called
- ``reloading''), perform the [Oadd] operation over these temporaries,
- leave the result in a temporary, then store the temporary back to
- stack location [S s1] (this is called ``spilling''). In other term,
- the generated LTL code has the following shape:
-<<
- IT1 <- Bgetstack s1;
- IT2 <- Bgetstack s2;
- IT1 <- Bop(Oadd, IT1 :: IT2 :: nil);
- Bsetstack s1 IT1;
->>
- This section provides functions that assist in choosing appropriate
- temporaries and inserting the required spilling and reloading
- operations. *)
-
-(** ** Allocation of temporary registers for reloading and spilling. *)
-
-(** [reg_for l] returns a machine register appropriate for working
- over the location [l]: either the machine register [m] if [l = R m],
- or a temporary register of [l]'s type if [l] is a stack slot. *)
-
-Definition reg_for (l: loc) : mreg :=
- match l with
- | R r => r
- | S s => match slot_type s with Tint => IT1 | Tfloat => FT1 end
- end.
-
-(** [regs_for ll] is similar, for a list of locations [ll] of length
- at most 3. We ensure that distinct temporaries are used for
- different elements of [ll]. *)
-
-Fixpoint regs_for_rec (locs: list loc) (itmps ftmps: list mreg)
- {struct locs} : list mreg :=
- match locs, itmps, ftmps with
- | l1 :: ls, it1 :: its, ft1 :: fts =>
- match l1 with
- | R r => r
- | S s => match slot_type s with Tint => it1 | Tfloat => ft1 end
- end
- :: regs_for_rec ls its fts
- | _, _, _ => nil
- end.
-
-Definition regs_for (locs: list loc) :=
- regs_for_rec locs (IT1 :: IT2 :: IT3 :: nil) (FT1 :: FT2 :: FT3 :: nil).
-
-(** ** Insertion of LTL reloads, stores and moves *)
+(** * Translation from RTL to LTL *)
Require Import LTL.
-(** [add_spill src dst k] prepends to [k] the instructions needed
- to assign location [dst] the value of machine register [mreg]. *)
-
-Definition add_spill (src: mreg) (dst: loc) (k: block) :=
- match dst with
- | R rd => if mreg_eq src rd then k else Bop Omove (src :: nil) rd k
- | S sl => Bsetstack src sl k
- end.
-
-(** [add_reload src dst k] prepends to [k] the instructions needed
- to assign machine register [mreg] the value of the location [src]. *)
-
-Definition add_reload (src: loc) (dst: mreg) (k: block) :=
- match src with
- | R rs => if mreg_eq rs dst then k else Bop Omove (rs :: nil) dst k
- | S sl => Bgetstack sl dst k
- end.
-
-(** [add_reloads] is similar for a list of locations (as sources)
- and a list of machine registers (as destinations). *)
-
-Fixpoint add_reloads (srcs: list loc) (dsts: list mreg) (k: block)
- {struct srcs} : block :=
- match srcs, dsts with
- | s1 :: sl, t1 :: tl =>
- add_reload s1 t1 (add_reloads sl tl k)
- | _, _ =>
- k
- end.
-
-(** [add_move src dst k] prepends to [k] the instructions that copy
- the value of location [src] into location [dst]. *)
-
-Definition add_move (src dst: loc) (k: block) :=
- if Loc.eq src dst then k else
- match src, dst with
- | R rs, _ =>
- add_spill rs dst k
- | _, R rd =>
- add_reload src rd k
- | S ss, S sd =>
- let tmp :=
- match slot_type ss with Tint => IT1 | Tfloat => FT1 end in
- add_reload src tmp (add_spill tmp dst k)
- end.
-
-(** [parallel_move srcs dsts k] is similar, but for a list of
- source locations and a list of destination locations of the same
- length. This is a parallel move, meaning that arbitrary overlap
- between the sources and destinations is permitted. *)
-
-Definition parallel_move (srcs dsts: list loc) (k: block) : block :=
- List.fold_right
- (fun p k => add_move (fst p) (snd p) k)
- k (parmove srcs dsts).
-
-(** ** Constructors for LTL instructions *)
-
-(** The following functions generate LTL instructions operating
- over the given locations. Appropriate reloading and spilling operations
- are added around the core LTL instruction. *)
-
-Definition add_op (op: operation) (args: list loc) (res: loc) (s: node) :=
- match is_move_operation op args with
- | Some src =>
- add_move src res (Bgoto s)
- | None =>
- let rargs := regs_for args in
- let rres := reg_for res in
- add_reloads args rargs (Bop op rargs rres (add_spill rres res (Bgoto s)))
- end.
-
-Definition add_load (chunk: memory_chunk) (addr: addressing)
- (args: list loc) (dst: loc) (s: node) :=
- let rargs := regs_for args in
- let rdst := reg_for dst in
- add_reloads args rargs
- (Bload chunk addr rargs rdst (add_spill rdst dst (Bgoto s))).
-
-Definition add_store (chunk: memory_chunk) (addr: addressing)
- (args: list loc) (src: loc) (s: node) :=
- match regs_for (src :: args) with
- | nil => Breturn (* never happens *)
- | rsrc :: rargs =>
- add_reloads (src :: args) (rsrc :: rargs)
- (Bstore chunk addr rargs rsrc (Bgoto s))
- end.
-
-Definition add_alloc (arg: loc) (res: loc) (s: node) :=
- add_reload arg Conventions.loc_alloc_argument
- (Balloc (add_spill Conventions.loc_alloc_result res (Bgoto s))).
-
-(** For function calls, we also add appropriate moves to and from
- the canonical locations for function arguments and function results,
- as dictated by the calling conventions. *)
-
-Definition add_call (sig: signature) (ros: loc + ident)
- (args: list loc) (res: loc) (s: node) :=
- let rargs := loc_arguments sig in
- let rres := loc_result sig in
- match ros with
- | inl fn =>
- (add_reload fn IT3
- (parallel_move args rargs
- (Bcall sig (inl _ IT3) (add_spill rres res (Bgoto s)))))
- | inr id =>
- parallel_move args rargs
- (Bcall sig (inr _ id) (add_spill rres res (Bgoto s)))
- end.
-
-Definition add_cond (cond: condition) (args: list loc) (ifso ifnot: node) :=
- let rargs := regs_for args in
- add_reloads args rargs (Bcond cond rargs ifso ifnot).
-
-(** For function returns, we add the appropriate move of the result
- to the conventional location for the function result. If the function
- returns with no value, we explicitly set the function result register
- to the [Vundef] value, for consistency with RTL's semantics. *)
-
-Definition add_return (sig: signature) (optarg: option loc) :=
- match optarg with
- | Some arg => add_reload arg (loc_result sig) Breturn
- | None => Bop Oundef nil (loc_result sig) Breturn
- end.
-
-(** For function entry points, we move from the parameter locations
- dictated by the calling convention to the locations of the function
- parameters. We also explicitly set to [Vundef] the locations
- of pseudo-registers that are live at function entry but are not
- parameters, again for consistency with RTL's semantics. *)
-
-Fixpoint add_undefs (ll: list loc) (b: block) {struct ll} : block :=
- match ll with
- | nil => b
- | R r :: ls => Bop Oundef nil r (add_undefs ls b)
- | S s :: ls => add_undefs ls b
- end.
-
-Definition add_entry (sig: signature) (params: list loc) (undefs: list loc)
- (s: node) :=
- parallel_move (loc_parameters sig) params (add_undefs undefs (Bgoto s)).
-
-(** * Translation from RTL to LTL *)
-
-(** Each [RTL] instruction translates to an [LTL] basic block.
+(** Each [RTL] instruction translates to an [LTL] instruction.
The register assignment [assign] returned by register allocation
is applied to the arguments and results of the RTL
- instruction, followed by an invocation of the appropriate [LTL]
- constructor function that will deal with spilling, reloading and
- calling conventions. In addition, dead instructions are eliminated.
+ instruction. Moreover, dead instructions and redundant moves
+ are eliminated (turned into a [Lnop] instruction).
Dead instructions are instructions without side-effects ([Iop] and
[Iload]) whose result register is dead, i.e. whose result value
- is never used. *)
+ is never used. Redundant moves are moves whose source and destination
+ are assigned the same location. *)
+
+Definition is_redundant_move
+ (op: operation) (args: list reg) (res: reg) (assign: reg -> loc) : bool :=
+ match is_move_operation op args with
+ | None => false
+ | Some src => if Loc.eq (assign src) (assign res) then true else false
+ end.
Definition transf_instr
(f: RTL.function) (live: PMap.t Regset.t) (assign: reg -> loc)
- (pc: node) (instr: RTL.instruction) : LTL.block :=
+ (pc: node) (instr: RTL.instruction) : LTL.instruction :=
match instr with
| Inop s =>
- Bgoto s
+ Lnop s
| Iop op args res s =>
if Regset.mem res live!!pc then
- add_op op (List.map assign args) (assign res) s
+ if is_redundant_move op args res assign then
+ Lnop s
+ else
+ Lop op (List.map assign args) (assign res) s
else
- Bgoto s
+ Lnop s
| Iload chunk addr args dst s =>
if Regset.mem dst live!!pc then
- add_load chunk addr (List.map assign args) (assign dst) s
+ Lload chunk addr (List.map assign args) (assign dst) s
else
- Bgoto s
+ Lnop s
| Istore chunk addr args src s =>
- add_store chunk addr (List.map assign args) (assign src) s
+ Lstore chunk addr (List.map assign args) (assign src) s
| Icall sig ros args res s =>
- add_call sig (sum_left_map assign ros) (List.map assign args)
- (assign res) s
+ Lcall sig (sum_left_map assign ros) (List.map assign args)
+ (assign res) s
+ | Itailcall sig ros args =>
+ Ltailcall sig (sum_left_map assign ros) (List.map assign args)
| Ialloc arg res s =>
- add_alloc (assign arg) (assign res) s
+ Lalloc (assign arg) (assign res) s
| Icond cond args ifso ifnot =>
- add_cond cond (List.map assign args) ifso ifnot
+ Lcond cond (List.map assign args) ifso ifnot
| Ireturn optarg =>
- add_return f.(RTL.fn_sig) (option_map assign optarg)
+ Lreturn (option_map assign optarg)
end.
-Definition transf_entrypoint
- (f: RTL.function) (live: PMap.t Regset.t) (assign: reg -> loc)
- (newcode: LTL.code) : LTL.code :=
- let oldentry := RTL.fn_entrypoint f in
- let newentry := RTL.fn_nextpc f in
- let undefs :=
- Regset.elements (reg_list_dead (RTL.fn_params f)
- (transfer f oldentry live!!oldentry)) in
- PTree.set
- newentry
- (add_entry (RTL.fn_sig f)
- (List.map assign (RTL.fn_params f))
- (List.map assign undefs)
- oldentry)
- newcode.
-
-Lemma transf_entrypoint_wf:
+Lemma transf_body_wf:
forall (f: RTL.function) (live: PMap.t Regset.t) (assign: reg -> loc),
- let tc1 := PTree.map (transf_instr f live assign) (RTL.fn_code f) in
- let tc2 := transf_entrypoint f live assign tc1 in
- forall (pc: node), Plt pc (Psucc (RTL.fn_nextpc f)) \/ tc2!pc = None.
+ let tc := PTree.map (transf_instr f live assign) (RTL.fn_code f) in
+ forall (pc: node), Plt pc (RTL.fn_nextpc f) \/ tc!pc = None.
Proof.
- intros. case (plt pc (Psucc (RTL.fn_nextpc f))); intro.
- left. auto.
- right.
- assert (pc <> RTL.fn_nextpc f).
- red; intro. subst pc. elim n. apply Plt_succ.
- assert (~ (Plt pc (RTL.fn_nextpc f))).
- red; intro. elim n. apply Plt_trans_succ; auto.
- unfold tc2. unfold transf_entrypoint.
- rewrite PTree.gso; auto.
- unfold tc1. rewrite PTree.gmap.
- elim (RTL.fn_code_wf f pc); intro.
- contradiction. unfold option_map. rewrite H1. auto.
+ intros. elim (RTL.fn_code_wf f pc); intro.
+ left. auto. right. unfold tc. rewrite PTree.gmap.
+ unfold option_map. rewrite H. auto.
Qed.
+Definition transf_fun (f: RTL.function) (live: PMap.t Regset.t)
+ (assign: reg -> loc) : LTL.function :=
+ LTL.mkfunction
+ (RTL.fn_sig f)
+ (List.map assign (RTL.fn_params f))
+ (RTL.fn_stacksize f)
+ (PTree.map (transf_instr f live assign) (RTL.fn_code f))
+ (RTL.fn_entrypoint f)
+ (RTL.fn_nextpc f)
+ (transf_body_wf f live assign).
+
(** The translation of a function performs liveness analysis,
construction and coloring of the inference graph, and per-instruction
transformation as described above. *)
-Definition transf_function (f: RTL.function) : option LTL.function :=
+Definition live0 (f: RTL.function) (live: PMap.t Regset.t) :=
+ transfer f f.(RTL.fn_entrypoint) live!!(f.(RTL.fn_entrypoint)).
+
+Open Scope string_scope.
+
+Definition transf_function (f: RTL.function) : res LTL.function :=
match type_function f with
- | None => None
- | Some env =>
+ | Error msg => Error msg
+ | OK env =>
match analyze f with
- | None => None
+ | None => Error (msg "Liveness analysis failure")
| Some live =>
- let pc0 := f.(RTL.fn_entrypoint) in
- let live0 := transfer f pc0 live!!pc0 in
- match regalloc f live live0 env with
- | None => None
- | Some assign =>
- Some (LTL.mkfunction
- (RTL.fn_sig f)
- (RTL.fn_stacksize f)
- (transf_entrypoint f live assign
- (PTree.map (transf_instr f live assign) (RTL.fn_code f)))
- (RTL.fn_nextpc f)
- (transf_entrypoint_wf f live assign))
- end
+ match regalloc f live (live0 f live) env with
+ | None => Error (msg "Incorrect graph coloring")
+ | Some assign => OK (transf_fun f live assign)
+ end
end
end.
-Definition transf_fundef (fd: RTL.fundef) : option LTL.fundef :=
- transf_partial_fundef transf_function fd.
+Definition transf_fundef (fd: RTL.fundef) : res LTL.fundef :=
+ AST.transf_partial_fundef transf_function fd.
-Definition transf_program (p: RTL.program) : option LTL.program :=
+Definition transf_program (p: RTL.program) : res LTL.program :=
transform_partial_program transf_fundef p.
diff --git a/backend/Allocproof.v b/backend/Allocproof.v
index f0b2968..1b5a415 100644
--- a/backend/Allocproof.v
+++ b/backend/Allocproof.v
@@ -1,16 +1,17 @@
(** Correctness proof for the [Allocation] pass (translation from
RTL to LTL). *)
-Require Import Relations.
Require Import FSets.
Require Import SetoidList.
Require Import Coqlib.
+Require Import Errors.
Require Import Maps.
Require Import AST.
Require Import Integers.
Require Import Values.
Require Import Mem.
Require Import Events.
+Require Import Smallstep.
Require Import Globalenvs.
Require Import Op.
Require Import Registers.
@@ -20,7 +21,6 @@ Require Import Locations.
Require Import Conventions.
Require Import Coloring.
Require Import Coloringproof.
-Require Import Parallelmove.
Require Import Allocation.
(** * Semantic properties of calling conventions *)
@@ -53,9 +53,27 @@ Proof.
auto.
case (In_dec Loc.eq (R (loc_result sig)) destroyed_at_call); intro.
auto.
- elim n0. apply loc_result_acceptable.
+ elim n0. apply loc_result_caller_save.
Qed.
+(** Function arguments for a tail call are preserved by a
+ [return_regs] operation. *)
+
+Lemma return_regs_arguments:
+ forall sig caller callee,
+ tailcall_possible sig ->
+ map (LTL.return_regs caller callee) (loc_arguments sig) =
+ map callee (loc_arguments sig).
+Proof.
+ intros. apply list_map_exten; intros.
+ generalize (H x H0). destruct x; intro.
+ unfold LTL.return_regs.
+ destruct (In_dec Loc.eq (R m) temporaries). auto.
+ destruct (In_dec Loc.eq (R m) destroyed_at_call). auto.
+ elim n0. eapply arguments_caller_save; eauto.
+ contradiction.
+Qed.
+
(** Acceptable locations that are not destroyed at call keep
their values across a call. *)
@@ -73,31 +91,22 @@ Proof.
auto.
Qed.
-(** * Correctness condition for the liveness analysis *)
-
-(** The liveness information computed by the dataflow analysis is
- correct in the following sense: all registers live ``before''
- an instruction are live ``after'' all of its predecessors. *)
+(** Characterization of parallel assignments. *)
-Lemma analyze_correct:
- forall (f: function) (live: PMap.t Regset.t) (n s: node),
- analyze f = Some live ->
- f.(fn_code)!n <> None ->
- f.(fn_code)!s <> None ->
- In s (successors f n) ->
- RegsetLat.ge live!!n (transfer f s live!!s).
+Lemma parmov_spec:
+ forall ls srcs dsts,
+ Loc.norepet dsts -> List.length srcs = List.length dsts ->
+ List.map (LTL.parmov srcs dsts ls) dsts = List.map ls srcs /\
+ (forall l, Loc.notin l dsts -> LTL.parmov srcs dsts ls l = ls l).
Proof.
- intros.
- eapply DS.fixpoint_solution.
- unfold analyze in H. eexact H.
- elim (fn_code_wf f n); intro. auto. contradiction.
- elim (fn_code_wf f s); intro. auto. contradiction.
+ induction srcs; destruct dsts; simpl; intros; try discriminate.
auto.
+ inv H. inv H0. destruct (IHsrcs _ H4 H1). split.
+ f_equal. apply Locmap.gss. rewrite <- H. apply list_map_exten; intros.
+ symmetry. apply Locmap.gso. eapply Loc.in_notin_diff; eauto.
+ intros x [A B]. rewrite Locmap.gso; auto. apply Loc.diff_sym; auto.
Qed.
-Definition live0 (f: RTL.function) (live: PMap.t Regset.t) :=
- transfer f f.(RTL.fn_entrypoint) live!!(f.(RTL.fn_entrypoint)).
-
(** * Properties of allocated locations *)
(** We list here various properties of the locations [alloc r],
@@ -112,19 +121,6 @@ Variable live: PMap.t Regset.t.
Variable alloc: reg -> loc.
Hypothesis ALLOC: regalloc f live (live0 f live) env = Some alloc.
-Lemma loc_acceptable_noteq_diff:
- forall l1 l2,
- loc_acceptable l1 -> l1 <> l2 -> Loc.diff l1 l2.
-Proof.
- unfold loc_acceptable, Loc.diff; destruct l1; destruct l2;
- try (destruct s); try (destruct s0); intros; auto; try congruence.
- case (zeq z z0); intro.
- compare t t0; intro.
- subst z0; subst t0; tauto.
- tauto. tauto.
- contradiction. contradiction.
-Qed.
-
Lemma regalloc_noteq_diff:
forall r1 l2,
alloc r1 <> l2 -> Loc.diff (alloc r1) l2.
@@ -134,18 +130,6 @@ Proof.
auto.
Qed.
-Lemma loc_acceptable_notin_notin:
- forall r ll,
- loc_acceptable r ->
- ~(In r ll) -> Loc.notin r ll.
-Proof.
- induction ll; simpl; intros.
- auto.
- split. apply loc_acceptable_noteq_diff. assumption.
- apply sym_not_equal. tauto.
- apply IHll. assumption. tauto.
-Qed.
-
Lemma regalloc_notin_notin:
forall r ll,
~(In (alloc r) ll) -> Loc.notin (alloc r) ll.
@@ -153,6 +137,15 @@ Proof.
intros. apply loc_acceptable_notin_notin.
eapply regalloc_acceptable; eauto. auto.
Qed.
+
+Lemma regalloc_notin_notin_2:
+ forall l rl,
+ ~(In l (map alloc rl)) -> Loc.notin l (map alloc rl).
+Proof.
+ induction rl; simpl; intros. auto.
+ split. apply Loc.diff_sym. apply regalloc_noteq_diff. tauto.
+ apply IHrl. tauto.
+Qed.
Lemma regalloc_norepet_norepet:
forall rl,
@@ -215,7 +208,7 @@ Hypothesis REGALLOC: regalloc f flive (live0 f flive) env = Some assign.
of [assign r] can be arbitrary. *)
Definition agree (live: Regset.t) (rs: regset) (ls: locset) : Prop :=
- forall (r: reg), Regset.In r live -> ls (assign r) = rs#r.
+ forall (r: reg), Regset.In r live -> Val.lessdef (rs#r) (ls (assign r)).
(** What follows is a long list of lemmas expressing properties
of the [agree_live_regs] predicate that are useful for the
@@ -232,6 +225,24 @@ Proof.
apply H0. apply H. auto.
Qed.
+Lemma agree_succ:
+ forall n s rs ls live,
+ analyze f = Some live ->
+ In s (RTL.successors f n) ->
+ agree live!!n rs ls ->
+ agree (transfer f s live!!s) rs ls.
+Proof.
+ intros.
+ elim (RTL.fn_code_wf f n); intro.
+ elim (RTL.fn_code_wf f s); intro.
+ apply agree_increasing with (live!!n).
+ eapply DS.fixpoint_solution. unfold analyze in H; eauto.
+ auto. auto. auto. auto.
+ unfold transfer. rewrite H3.
+ red; intros. elim (Regset.empty_1 _ H4).
+ unfold RTL.successors in H0; rewrite H2 in H0; elim H0.
+Qed.
+
(** Some useful special cases of [agree_increasing]. *)
@@ -266,7 +277,7 @@ Qed.
Lemma agree_eval_reg:
forall r live rs ls,
- agree (reg_live r live) rs ls -> ls (assign r) = rs#r.
+ agree (reg_live r live) rs ls -> Val.lessdef (rs#r) (ls (assign r)).
Proof.
intros. apply H. apply Regset.add_1. auto.
Qed.
@@ -276,11 +287,11 @@ Qed.
Lemma agree_eval_regs:
forall rl live rs ls,
agree (reg_list_live rl live) rs ls ->
- List.map ls (List.map assign rl) = rs##rl.
+ Val.lessdef_list (rs##rl) (List.map ls (List.map assign rl)).
Proof.
induction rl; simpl; intros.
- reflexivity.
- apply (f_equal2 (@cons val)).
+ constructor.
+ constructor.
apply agree_eval_reg with live.
apply agree_reg_list_live with rl. auto.
eapply IHrl. eexact H.
@@ -322,21 +333,18 @@ Qed.
are mapped to locations other than that of [r]. *)
Lemma agree_assign_live:
- forall live r rs ls ls' v,
+ forall live r rs ls v v',
(forall s,
Regset.In s live -> s <> r -> assign s <> assign r) ->
- ls' (assign r) = v ->
- (forall l, Loc.diff l (assign r) -> Loc.notin l temporaries -> ls' l = ls l) ->
+ Val.lessdef v v' ->
agree (reg_dead r live) rs ls ->
- agree live (rs#r <- v) ls'.
+ agree live (rs#r <- v) (Locmap.set (assign r) v' ls).
Proof.
- unfold agree; intros.
- case (Reg.eq r r0); intro.
- subst r0. rewrite Regmap.gss. assumption.
- rewrite Regmap.gso; auto.
- rewrite H1. apply H2. apply Regset.remove_2; auto.
- eapply regalloc_noteq_diff. eauto. apply H. auto. auto.
- eapply regalloc_not_temporary; eauto.
+ unfold agree; intros. rewrite Regmap.gsspec.
+ destruct (peq r0 r).
+ subst r0. rewrite Locmap.gss. auto.
+ rewrite Locmap.gso. apply H1. apply Regset.remove_2; auto.
+ eapply regalloc_noteq_diff. eauto. apply sym_not_equal. apply H. auto. auto.
Qed.
(** This is a special case of the previous lemma where the value [v]
@@ -347,30 +355,47 @@ Qed.
are mapped to locations other than that of [res]. *)
Lemma agree_move_live:
- forall live arg res rs (ls ls': locset),
+ forall live arg res rs (ls: locset),
(forall r,
Regset.In r live -> r <> res -> r <> arg ->
assign r <> assign res) ->
- ls' (assign res) = ls (assign arg) ->
- (forall l, Loc.diff l (assign res) -> Loc.notin l temporaries -> ls' l = ls l) ->
agree (reg_live arg (reg_dead res live)) rs ls ->
- agree live (rs#res <- (rs#arg)) ls'.
+ agree live (rs#res <- (rs#arg)) (Locmap.set (assign res) (ls (assign arg)) ls).
Proof.
- unfold agree; intros.
- case (Reg.eq res r); intro.
- subst r. rewrite Regmap.gss. rewrite H0. apply H2.
+ unfold agree; intros. rewrite Regmap.gsspec. destruct (peq r res).
+ subst r. rewrite Locmap.gss. apply H0.
apply Regset.add_1; auto.
- rewrite Regmap.gso; auto.
- case (Loc.eq (assign r) (assign res)); intro.
- rewrite e. rewrite H0.
- case (Reg.eq arg r); intro.
- subst r. apply H2. apply Regset.add_1; auto.
- elim (H r); auto.
- rewrite H1. apply H2.
- case (Reg.eq arg r); intro. subst r. apply Regset.add_1; auto.
- apply Regset.add_2. apply Regset.remove_2. auto. auto.
- eapply regalloc_noteq_diff; eauto.
- eapply regalloc_not_temporary; eauto.
+ destruct (Reg.eq r arg).
+ subst r.
+ replace (Locmap.set (assign res) (ls (assign arg)) ls (assign arg))
+ with (ls (assign arg)).
+ apply H0. apply Regset.add_1. auto.
+ symmetry. destruct (Loc.eq (assign arg) (assign res)).
+ rewrite <- e. apply Locmap.gss.
+ apply Locmap.gso. eapply regalloc_noteq_diff; eauto.
+
+ rewrite Locmap.gso. apply H0. apply Regset.add_2. apply Regset.remove_2. auto. auto.
+ eapply regalloc_noteq_diff; eauto. apply sym_not_equal. apply H; auto.
+Qed.
+
+(** Yet another special case corresponding to the case of
+ a redundant move. *)
+
+Lemma agree_redundant_move_live:
+ forall live arg res rs (ls: locset),
+ (forall r,
+ Regset.In r live -> r <> res -> r <> arg ->
+ assign r <> assign res) ->
+ agree (reg_live arg (reg_dead res live)) rs ls ->
+ assign res = assign arg ->
+ agree live (rs#res <- (rs#arg)) ls.
+Proof.
+ intros.
+ apply agree_exten with (Locmap.set (assign res) (ls (assign arg)) ls).
+ eapply agree_move_live; eauto.
+ intros. symmetry. rewrite H1. destruct (Loc.eq l (assign arg)).
+ subst l. apply Locmap.gss.
+ apply Locmap.gso. eapply regalloc_noteq_diff; eauto.
Qed.
(** This complicated lemma states agreement between the states after
@@ -384,7 +409,7 @@ Lemma agree_call:
~(In (assign r) Conventions.destroyed_at_call)) ->
(forall r,
Regset.In r live -> r <> res -> assign r <> assign res) ->
- ls' (assign res) = v ->
+ Val.lessdef v (ls' (assign res)) ->
(forall l,
Loc.notin l destroyed_at_call -> loc_acceptable l -> Loc.diff l (assign res) ->
ls' l = ls l) ->
@@ -413,757 +438,33 @@ Lemma agree_init_regs:
(forall r1 r2,
In r1 rl -> Regset.In r2 live -> r1 <> r2 ->
assign r1 <> assign r2) ->
- List.map ls (List.map assign rl) = vl ->
- agree (reg_list_dead rl live) (Regmap.init Vundef) ls ->
+ Val.lessdef_list vl (List.map ls (List.map assign rl)) ->
agree live (init_regs vl rl) ls.
Proof.
induction rl; simpl; intros.
- assumption.
- destruct vl. discriminate.
- assert (agree (reg_dead a live) (init_regs vl rl) ls).
- apply IHrl. intros. apply H. tauto.
- eapply Regset.remove_3; eauto.
- auto. congruence. assumption.
+ red; intros. rewrite Regmap.gi. auto.
+ inv H0.
+ assert (agree live (init_regs vl1 rl) ls).
+ apply IHrl. intros. apply H. tauto. auto. auto. auto.
red; intros. case (Reg.eq a r); intro.
- subst r. rewrite Regmap.gss. congruence.
- rewrite Regmap.gso; auto. apply H2.
- apply Regset.remove_2; auto.
+ subst r. rewrite Regmap.gss. auto.
+ rewrite Regmap.gso; auto.
Qed.
Lemma agree_parameters:
forall vl ls,
let params := f.(RTL.fn_params) in
- List.map ls (List.map assign params) = vl ->
- (forall r,
- Regset.In r (reg_list_dead params (live0 f flive)) ->
- ls (assign r) = Vundef) ->
- agree (live0 f flive) (init_regs vl params) ls.
+ Val.lessdef_list vl (List.map ls (List.map assign params)) ->
+ agree (live0 f flive)
+ (init_regs vl params)
+ ls.
Proof.
intros. apply agree_init_regs.
intros. eapply regalloc_correct_3; eauto.
- assumption.
- red; intros. rewrite Regmap.gi. auto.
-Qed.
-
-End AGREE.
-
-(** * Correctness of the LTL constructors *)
-
-(** This section proves theorems that establish the correctness of the
- LTL constructor functions such as [add_op]. The theorems are of
- the general form ``the generated LTL instructions execute and
- modify the location set in the expected way: the result location(s)
- contain the expected values and other, non-temporary locations keep
- their values''. *)
-
-Section LTL_CONSTRUCTORS.
-
-Variable ge: LTL.genv.
-Variable sp: val.
-
-Lemma reg_for_spec:
- forall l,
- R(reg_for l) = l \/ In (R (reg_for l)) temporaries.
-Proof.
- intros. unfold reg_for. destruct l. tauto.
- case (slot_type s); simpl; tauto.
-Qed.
-
-Lemma add_reload_correct:
- forall src dst k rs m,
- exists rs',
- exec_instrs ge sp (add_reload src dst k) rs m E0 k rs' m /\
- rs' (R dst) = rs src /\
- forall l, Loc.diff (R dst) l -> rs' l = rs l.
-Proof.
- intros. unfold add_reload. destruct src.
- case (mreg_eq m0 dst); intro.
- subst dst. exists rs. split. apply exec_refl. tauto.
- exists (Locmap.set (R dst) (rs (R m0)) rs).
- split. apply exec_one; apply exec_Bop. reflexivity.
- split. apply Locmap.gss.
- intros; apply Locmap.gso; auto.
- exists (Locmap.set (R dst) (rs (S s)) rs).
- split. apply exec_one; apply exec_Bgetstack.
- split. apply Locmap.gss.
- intros; apply Locmap.gso; auto.
-Qed.
-
-Lemma add_spill_correct:
- forall src dst k rs m,
- exists rs',
- exec_instrs ge sp (add_spill src dst k) rs m E0 k rs' m /\
- rs' dst = rs (R src) /\
- forall l, Loc.diff dst l -> rs' l = rs l.
-Proof.
- intros. unfold add_spill. destruct dst.
- case (mreg_eq src m0); intro.
- subst src. exists rs. split. apply exec_refl. tauto.
- exists (Locmap.set (R m0) (rs (R src)) rs).
- split. apply exec_one. apply exec_Bop. reflexivity.
- split. apply Locmap.gss.
- intros; apply Locmap.gso; auto.
- exists (Locmap.set (S s) (rs (R src)) rs).
- split. apply exec_one. apply exec_Bsetstack.
- split. apply Locmap.gss.
- intros; apply Locmap.gso; auto.
-Qed.
-
-Lemma add_reloads_correct_rec:
- forall srcs itmps ftmps k rs m,
- (List.length srcs <= List.length itmps)%nat ->
- (List.length srcs <= List.length ftmps)%nat ->
- (forall r, In (R r) srcs -> In r itmps -> False) ->
- (forall r, In (R r) srcs -> In r ftmps -> False) ->
- list_disjoint itmps ftmps ->
- list_norepet itmps ->
- list_norepet ftmps ->
- exists rs',
- exec_instrs ge sp (add_reloads srcs (regs_for_rec srcs itmps ftmps) k) rs m E0 k rs' m /\
- reglist (regs_for_rec srcs itmps ftmps) rs' = map rs srcs /\
- (forall r, ~(In r itmps) -> ~(In r ftmps) -> rs' (R r) = rs (R r)) /\
- (forall s, rs' (S s) = rs (S s)).
-Proof.
- induction srcs; simpl; intros.
- (* base case *)
- exists rs. split. apply exec_refl. tauto.
- (* inductive case *)
- destruct itmps; simpl in H. omegaContradiction.
- destruct ftmps; simpl in H0. omegaContradiction.
- assert (R1: (length srcs <= length itmps)%nat). omega.
- assert (R2: (length srcs <= length ftmps)%nat). omega.
- assert (R3: forall r, In (R r) srcs -> In r itmps -> False).
- intros. apply H1 with r. tauto. auto with coqlib.
- assert (R4: forall r, In (R r) srcs -> In r ftmps -> False).
- intros. apply H2 with r. tauto. auto with coqlib.
- assert (R5: list_disjoint itmps ftmps).
- eapply list_disjoint_cons_left.
- eapply list_disjoint_cons_right. eauto.
- assert (R6: list_norepet itmps).
- inversion H4; auto.
- assert (R7: list_norepet ftmps).
- inversion H5; auto.
- destruct a.
- (* a is a register *)
- generalize (IHsrcs itmps ftmps k rs m R1 R2 R3 R4 R5 R6 R7).
- intros [rs' [EX [RES [OTH1 OTH2]]]].
- exists rs'. split.
- unfold add_reload. case (mreg_eq m2 m2); intro; tauto.
- split. simpl. apply (f_equal2 (@cons val)).
- apply OTH1.
- red; intro; apply H1 with m2. tauto. auto with coqlib.
- red; intro; apply H2 with m2. tauto. auto with coqlib.
- assumption.
- split. intros. apply OTH1. simpl in H6; tauto. simpl in H7; tauto.
- auto.
- (* a is a stack location *)
- set (tmp := match slot_type s with Tint => m0 | Tfloat => m1 end).
- assert (NI: ~(In tmp itmps)).
- unfold tmp; case (slot_type s).
- inversion H4; auto.
- apply list_disjoint_notin with (m1 :: ftmps).
- apply list_disjoint_sym. apply list_disjoint_cons_left with m0.
- auto. auto with coqlib.
- assert (NF: ~(In tmp ftmps)).
- unfold tmp; case (slot_type s).
- apply list_disjoint_notin with (m0 :: itmps).
- apply list_disjoint_cons_right with m1.
- auto. auto with coqlib.
- inversion H5; auto.
- generalize
- (add_reload_correct (S s) tmp
- (add_reloads srcs (regs_for_rec srcs itmps ftmps) k) rs m).
- intros [rs1 [EX1 [RES1 OTH]]].
- generalize (IHsrcs itmps ftmps k rs1 m R1 R2 R3 R4 R5 R6 R7).
- intros [rs' [EX [RES [OTH1 OTH2]]]].
- exists rs'.
- split. eapply exec_trans; eauto. traceEq.
- split. simpl. apply (f_equal2 (@cons val)).
- rewrite OTH1; auto.
- rewrite RES. apply list_map_exten. intros.
- symmetry. apply OTH.
- destruct x; try exact I. simpl. red; intro; subst m2.
- generalize H6; unfold tmp. case (slot_type s).
- intro. apply H1 with m0. tauto. auto with coqlib.
- intro. apply H2 with m1. tauto. auto with coqlib.
- split. intros. simpl in H6; simpl in H7.
- rewrite OTH1. apply OTH.
- simpl. unfold tmp. case (slot_type s); tauto.
- tauto. tauto.
- intros. rewrite OTH2. apply OTH. exact I.
-Qed.
-
-Lemma add_reloads_correct:
- forall srcs k rs m,
- (List.length srcs <= 3)%nat ->
- Loc.disjoint srcs temporaries ->
- exists rs',
- exec_instrs ge sp (add_reloads srcs (regs_for srcs) k) rs m E0 k rs' m /\
- reglist (regs_for srcs) rs' = List.map rs srcs /\
- forall l, Loc.notin l temporaries -> rs' l = rs l.
-Proof.
- intros.
- pose (itmps := IT1 :: IT2 :: IT3 :: nil).
- pose (ftmps := FT1 :: FT2 :: FT3 :: nil).
- assert (R1: (List.length srcs <= List.length itmps)%nat).
- unfold itmps; simpl; assumption.
- assert (R2: (List.length srcs <= List.length ftmps)%nat).
- unfold ftmps; simpl; assumption.
- assert (R3: forall r, In (R r) srcs -> In r itmps -> False).
- intros. assert (In (R r) temporaries).
- simpl in H2; simpl; intuition congruence.
- generalize (H0 _ _ H1 H3). simpl. tauto.
- assert (R4: forall r, In (R r) srcs -> In r ftmps -> False).
- intros. assert (In (R r) temporaries).
- simpl in H2; simpl; intuition congruence.
- generalize (H0 _ _ H1 H3). simpl. tauto.
- assert (R5: list_disjoint itmps ftmps).
- red; intros r1 r2; simpl; intuition congruence.
- assert (R6: list_norepet itmps).
- unfold itmps. NoRepet.
- assert (R7: list_norepet ftmps).
- unfold ftmps. NoRepet.
- generalize (add_reloads_correct_rec srcs itmps ftmps k rs m
- R1 R2 R3 R4 R5 R6 R7).
- intros [rs' [EX [RES [OTH1 OTH2]]]].
- exists rs'. split. exact EX.
- split. exact RES.
- intros. destruct l. apply OTH1.
- generalize (Loc.notin_not_in _ _ H1). simpl. intuition congruence.
- generalize (Loc.notin_not_in _ _ H1). simpl. intuition congruence.
- apply OTH2.
-Qed.
-
-Lemma add_move_correct:
- forall src dst k rs m,
- exists rs',
- exec_instrs ge sp (add_move src dst k) rs m E0 k rs' m /\
- rs' dst = rs src /\
- forall l, Loc.diff l dst -> Loc.diff l (R IT1) -> Loc.diff l (R FT1) -> rs' l = rs l.
-Proof.
- intros; unfold add_move.
- case (Loc.eq src dst); intro.
- subst dst. exists rs. split. apply exec_refl. tauto.
- destruct src.
- (* src is a register *)
- generalize (add_spill_correct m0 dst k rs m); intros [rs' [EX [RES OTH]]].
- exists rs'; intuition. apply OTH; apply Loc.diff_sym; auto.
- destruct dst.
- (* src is a stack slot, dst a register *)
- generalize (add_reload_correct (S s) m0 k rs m); intros [rs' [EX [RES OTH]]].
- exists rs'; intuition. apply OTH; apply Loc.diff_sym; auto.
- (* src and dst are stack slots *)
- set (tmp := match slot_type s with Tint => IT1 | Tfloat => FT1 end).
- generalize (add_reload_correct (S s) tmp (add_spill tmp (S s0) k) rs m);
- intros [rs1 [EX1 [RES1 OTH1]]].
- generalize (add_spill_correct tmp (S s0) k rs1 m);
- intros [rs2 [EX2 [RES2 OTH2]]].
- exists rs2. split.
- eapply exec_trans; eauto. traceEq.
- split. congruence.
- intros. rewrite OTH2. apply OTH1.
- apply Loc.diff_sym. unfold tmp; case (slot_type s); auto.
- apply Loc.diff_sym; auto.
-Qed.
-
-Lemma effect_move_sequence:
- forall k moves rs m,
- let k' := List.fold_right (fun p k => add_move (fst p) (snd p) k) k moves in
- exists rs',
- exec_instrs ge sp k' rs m E0 k rs' m /\
- effect_seqmove moves rs rs'.
-Proof.
- induction moves; intros until m; simpl.
- exists rs; split. constructor. constructor.
- destruct a as [src dst]; simpl.
- set (k1 := fold_right
- (fun (p : loc * loc) (k : block) => add_move (fst p) (snd p) k)
- k moves) in *.
- destruct (add_move_correct src dst k1 rs m) as [rs1 [A [B C]]].
- destruct (IHmoves rs1 m) as [rs' [D E]].
- exists rs'; split.
- eapply exec_trans; eauto. traceEq.
- econstructor; eauto. red. tauto.
-Qed.
-
-Theorem parallel_move_correct:
- forall srcs dsts k rs m,
- List.length srcs = List.length dsts ->
- Loc.no_overlap srcs dsts ->
- Loc.norepet dsts ->
- Loc.disjoint srcs temporaries ->
- Loc.disjoint dsts temporaries ->
- exists rs',
- exec_instrs ge sp (parallel_move srcs dsts k) rs m E0 k rs' m /\
- List.map rs' dsts = List.map rs srcs /\
- rs' (R IT3) = rs (R IT3) /\
- forall l, Loc.notin l dsts -> Loc.notin l temporaries -> rs' l = rs l.
-Proof.
- intros.
- generalize (effect_move_sequence k (parmove srcs dsts) rs m).
- intros [rs' [EXEC EFFECT]].
- exists rs'. split. exact EXEC.
- apply effect_parmove; auto.
-Qed.
-
-Lemma add_op_correct:
- forall op args res s rs m v,
- (List.length args <= 3)%nat ->
- Loc.disjoint args temporaries ->
- eval_operation ge sp op (List.map rs args) = Some v ->
- exists rs',
- exec_block ge sp (add_op op args res s) rs m E0 (Cont s) rs' m /\
- rs' res = v /\
- forall l, Loc.diff l res -> Loc.notin l temporaries -> rs' l = rs l.
-Proof.
- intros. unfold add_op.
- caseEq (is_move_operation op args).
- (* move *)
- intros arg IMO.
- generalize (is_move_operation_correct op args IMO).
- intros [EQ1 EQ2]. subst op; subst args.
- generalize (add_move_correct arg res (Bgoto s) rs m).
- intros [rs' [EX [RES OTHER]]].
- exists rs'. split.
- apply exec_Bgoto. exact EX.
- split. simpl in H1. congruence.
- intros. unfold temporaries in H3; simpl in H3.
- apply OTHER. assumption. tauto. tauto.
- (* other ops *)
- intros.
- set (rargs := regs_for args). set (rres := reg_for res).
- generalize (add_reloads_correct args
- (Bop op rargs rres (add_spill rres res (Bgoto s)))
- rs m H H0).
- intros [rs1 [EX1 [RES1 OTHER1]]].
- pose (rs2 := Locmap.set (R rres) v rs1).
- generalize (add_spill_correct rres res (Bgoto s) rs2 m).
- intros [rs3 [EX3 [RES3 OTHER3]]].
- exists rs3.
- split. apply exec_Bgoto. eapply exec_trans. eexact EX1.
- eapply exec_trans; eauto.
- apply exec_one. unfold rs2. apply exec_Bop.
- unfold rargs. rewrite RES1. auto. traceEq.
- split. rewrite RES3. unfold rs2; apply Locmap.gss.
- intros. rewrite OTHER3. unfold rs2. rewrite Locmap.gso.
- apply OTHER1. assumption.
- apply Loc.diff_sym. unfold rres. elim (reg_for_spec res); intro.
- rewrite H5; auto.
- eapply Loc.in_notin_diff; eauto. apply Loc.diff_sym; auto.
-Qed.
-
-Lemma add_load_correct:
- forall chunk addr args res s rs m a v,
- (List.length args <= 2)%nat ->
- Loc.disjoint args temporaries ->
- eval_addressing ge sp addr (List.map rs args) = Some a ->
- loadv chunk m a = Some v ->
- exists rs',
- exec_block ge sp (add_load chunk addr args res s) rs m E0 (Cont s) rs' m /\
- rs' res = v /\
- forall l, Loc.diff l res -> Loc.notin l temporaries -> rs' l = rs l.
-Proof.
- intros. unfold add_load.
- set (rargs := regs_for args). set (rres := reg_for res).
- assert (LL: (List.length args <= 3)%nat). omega.
- generalize (add_reloads_correct args
- (Bload chunk addr rargs rres (add_spill rres res (Bgoto s)))
- rs m LL H0).
- intros [rs1 [EX1 [RES1 OTHER1]]].
- pose (rs2 := Locmap.set (R rres) v rs1).
- generalize (add_spill_correct rres res (Bgoto s) rs2 m).
- intros [rs3 [EX3 [RES3 OTHER3]]].
- exists rs3.
- split. apply exec_Bgoto. eapply exec_trans; eauto.
- eapply exec_trans; eauto.
- apply exec_one. unfold rs2. apply exec_Bload with a.
- unfold rargs; rewrite RES1. assumption. assumption. traceEq.
- split. rewrite RES3. unfold rs2; apply Locmap.gss.
- intros. rewrite OTHER3. unfold rs2. rewrite Locmap.gso.
- apply OTHER1. assumption.
- apply Loc.diff_sym. unfold rres. elim (reg_for_spec res); intro.
- rewrite H5; auto.
- eapply Loc.in_notin_diff; eauto. apply Loc.diff_sym; auto.
-Qed.
-
-Lemma add_store_correct:
- forall chunk addr args src s rs m m' a,
- (List.length args <= 2)%nat ->
- Loc.disjoint args temporaries ->
- Loc.notin src temporaries ->
- eval_addressing ge sp addr (List.map rs args) = Some a ->
- storev chunk m a (rs src) = Some m' ->
- exists rs',
- exec_block ge sp (add_store chunk addr args src s) rs m E0 (Cont s) rs' m' /\
- forall l, Loc.notin l temporaries -> rs' l = rs l.
-Proof.
- intros.
- assert (LL: (List.length (src :: args) <= 3)%nat).
- simpl. omega.
- assert (DISJ: Loc.disjoint (src :: args) temporaries).
- red; intros. elim H4; intro. subst x1.
- eapply Loc.in_notin_diff; eauto.
- auto with coqlib.
- unfold add_store. caseEq (regs_for (src :: args)).
- unfold regs_for; simpl; intro; discriminate.
- intros rsrc rargs EQ.
- generalize (add_reloads_correct (src :: args)
- (Bstore chunk addr rargs rsrc (Bgoto s))
- rs m LL DISJ).
- intros [rs1 [EX1 [RES1 OTHER1]]].
- rewrite EQ in RES1. simpl in RES1. injection RES1.
- intros RES2 RES3.
- exists rs1.
- split. apply exec_Bgoto.
- eapply exec_trans. rewrite <- EQ. eexact EX1.
- apply exec_one. apply exec_Bstore with a.
- rewrite RES2. assumption. rewrite RES3. assumption. traceEq.
- exact OTHER1.
-Qed.
-
-Lemma add_alloc_correct:
- forall arg res s rs m m' sz b,
- rs arg = Vint sz ->
- Mem.alloc m 0 (Int.signed sz) = (m', b) ->
- exists rs',
- exec_block ge sp (add_alloc arg res s) rs m E0 (Cont s) rs' m' /\
- rs' res = Vptr b Int.zero /\
- forall l,
- Loc.diff l (R Conventions.loc_alloc_argument) ->
- Loc.diff l (R Conventions.loc_alloc_result) ->
- Loc.diff l res ->
- rs' l = rs l.
-Proof.
- intros; unfold add_alloc.
- generalize (add_reload_correct arg loc_alloc_argument
- (Balloc (add_spill loc_alloc_result res (Bgoto s)))
- rs m).
- intros [rs1 [EX1 [RES1 OTHER1]]].
- pose (rs2 := Locmap.set (R loc_alloc_result) (Vptr b Int.zero) rs1).
- generalize (add_spill_correct loc_alloc_result res (Bgoto s) rs2 m').
- intros [rs3 [EX3 [RES3 OTHER3]]].
- exists rs3.
- split. apply exec_Bgoto. eapply exec_trans. eexact EX1.
- eapply exec_trans. apply exec_one. eapply exec_Balloc; eauto. congruence.
- fold rs2. eexact EX3. reflexivity. traceEq.
- split. rewrite RES3; unfold rs2. apply Locmap.gss.
- intros. rewrite OTHER3. unfold rs2. rewrite Locmap.gso.
- apply OTHER1. apply Loc.diff_sym; auto.
- apply Loc.diff_sym; auto.
- apply Loc.diff_sym; auto.
-Qed.
-
-Lemma add_cond_correct:
- forall cond args ifso ifnot rs m b s,
- (List.length args <= 3)%nat ->
- Loc.disjoint args temporaries ->
- eval_condition cond (List.map rs args) = Some b ->
- s = (if b then ifso else ifnot) ->
- exists rs',
- exec_block ge sp (add_cond cond args ifso ifnot) rs m E0 (Cont s) rs' m /\
- forall l, Loc.notin l temporaries -> rs' l = rs l.
-Proof.
- intros. unfold add_cond.
- set (rargs := regs_for args).
- generalize (add_reloads_correct args
- (Bcond cond rargs ifso ifnot)
- rs m H H0).
- intros [rs1 [EX1 [RES1 OTHER1]]].
- fold rargs in EX1.
- exists rs1.
- split. destruct b; subst s.
- eapply exec_Bcond_true. eexact EX1.
- unfold rargs; rewrite RES1. assumption.
- eapply exec_Bcond_false. eexact EX1.
- unfold rargs; rewrite RES1. assumption.
- exact OTHER1.
-Qed.
-
-Definition find_function2 (los: loc + ident) (ls: locset) : option fundef :=
- match los with
- | inl l => Genv.find_funct ge (ls l)
- | inr symb =>
- match Genv.find_symbol ge symb with
- | None => None
- | Some b => Genv.find_funct_ptr ge b
- end
- end.
-
-Lemma add_call_correct:
- forall f vargs m t vres m' sig los args res s ls
- (EXECF:
- forall lsi,
- List.map lsi (loc_arguments (funsig f)) = vargs ->
- exists lso,
- exec_function ge f lsi m t lso m'
- /\ lso (R (loc_result (funsig f))) = vres)
- (FIND: find_function2 los ls = Some f)
- (SIG: sig = funsig f)
- (VARGS: List.map ls args = vargs)
- (LARGS: List.length args = List.length sig.(sig_args))
- (AARGS: locs_acceptable args)
- (RES: loc_acceptable res),
- exists ls',
- exec_block ge sp (add_call sig los args res s) ls m t (Cont s) ls' m' /\
- ls' res = vres /\
- forall l,
- Loc.notin l destroyed_at_call -> loc_acceptable l -> Loc.diff l res ->
- ls' l = ls l.
-Proof.
- intros until los.
- case los; intro fn; intros; simpl in FIND; rewrite <- SIG in EXECF; unfold add_call.
- (* indirect call *)
- assert (LEN: List.length args = List.length (loc_arguments sig)).
- rewrite LARGS. symmetry. apply loc_arguments_length.
- pose (DISJ := locs_acceptable_disj_temporaries args AARGS).
- generalize (add_reload_correct fn IT3
- (parallel_move args (loc_arguments sig)
- (Bcall sig (inl ident IT3)
- (add_spill (loc_result sig) res (Bgoto s))))
- ls m).
- intros [ls1 [EX1 [RES1 OTHER1]]].
- generalize
- (parallel_move_correct args (loc_arguments sig)
- (Bcall sig (inl ident IT3)
- (add_spill (loc_result sig) res (Bgoto s)))
- ls1 m LEN
- (no_overlap_arguments args sig AARGS)
- (loc_arguments_norepet sig)
- DISJ
- (loc_arguments_not_temporaries sig)).
- intros [ls2 [EX2 [RES2 [TMP2 OTHER2]]]].
- assert (PARAMS: List.map ls2 (loc_arguments sig) = vargs).
- rewrite <- VARGS. rewrite RES2.
- apply list_map_exten. intros. symmetry. apply OTHER1.
- apply Loc.diff_sym. apply DISJ. auto. simpl; tauto.
- generalize (EXECF ls2 PARAMS).
- intros [ls3 [EX3 RES3]].
- pose (ls4 := return_regs ls2 ls3).
- generalize (add_spill_correct (loc_result sig) res
- (Bgoto s) ls4 m').
- intros [ls5 [EX5 [RES5 OTHER5]]].
- exists ls5.
- (* Execution *)
- split. apply exec_Bgoto.
- eapply exec_trans. eexact EX1.
- eapply exec_trans. eexact EX2.
- eapply exec_trans. apply exec_one. apply exec_Bcall with f.
- unfold find_function. rewrite TMP2. rewrite RES1.
- assumption. assumption. eexact EX3.
- eexact EX5. reflexivity. reflexivity. traceEq.
- (* Result *)
- split. rewrite RES5. unfold ls4. rewrite return_regs_result.
- assumption.
- (* Other regs *)
- intros. rewrite OTHER5; auto.
- unfold ls4; rewrite return_regs_not_destroyed; auto.
- rewrite OTHER2. apply OTHER1.
- apply Loc.diff_sym. apply Loc.in_notin_diff with temporaries.
- apply temporaries_not_acceptable; auto. simpl; tauto.
- apply arguments_not_preserved; auto.
- apply temporaries_not_acceptable; auto.
- apply Loc.diff_sym; auto.
- (* direct call *)
- assert (LEN: List.length args = List.length (loc_arguments sig)).
- rewrite LARGS. symmetry. apply loc_arguments_length.
- pose (DISJ := locs_acceptable_disj_temporaries args AARGS).
- generalize
- (parallel_move_correct args (loc_arguments sig)
- (Bcall sig (inr mreg fn)
- (add_spill (loc_result sig) res (Bgoto s)))
- ls m LEN
- (no_overlap_arguments args sig AARGS)
- (loc_arguments_norepet sig)
- DISJ (loc_arguments_not_temporaries sig)).
- intros [ls2 [EX2 [RES2 [TMP2 OTHER2]]]].
- assert (PARAMS: List.map ls2 (loc_arguments sig) = vargs).
- rewrite <- VARGS. rewrite RES2. auto.
- generalize (EXECF ls2 PARAMS).
- intros [ls3 [EX3 RES3]].
- pose (ls4 := return_regs ls2 ls3).
- generalize (add_spill_correct (loc_result sig) res
- (Bgoto s) ls4 m').
- intros [ls5 [EX5 [RES5 OTHER5]]].
- exists ls5.
- (* Execution *)
- split. apply exec_Bgoto.
- eapply exec_trans. eexact EX2.
- eapply exec_trans. apply exec_one. apply exec_Bcall with f.
- unfold find_function. assumption. assumption. eexact EX3.
- eexact EX5. reflexivity. traceEq.
- (* Result *)
- split. rewrite RES5.
- unfold ls4. rewrite return_regs_result.
- assumption.
- (* Other regs *)
- intros. rewrite OTHER5; auto.
- unfold ls4; rewrite return_regs_not_destroyed; auto.
- apply OTHER2.
- apply arguments_not_preserved; auto.
- apply temporaries_not_acceptable; auto.
- apply Loc.diff_sym; auto.
-Qed.
-
-Lemma add_undefs_correct:
- forall res b ls m,
- (forall l, In l res -> loc_acceptable l) ->
- (forall ofs ty, In (S (Local ofs ty)) res -> ls (S (Local ofs ty)) = Vundef) ->
- exists ls',
- exec_instrs ge sp (add_undefs res b) ls m E0 b ls' m /\
- (forall l, In l res -> ls' l = Vundef) /\
- (forall l, Loc.notin l res -> ls' l = ls l).
-Proof.
- induction res; simpl; intros.
- exists ls. split. apply exec_refl. tauto.
- assert (ACC: forall l, In l res -> loc_acceptable l).
- intros. apply H. tauto.
- destruct a.
- (* a is a register *)
- pose (ls1 := Locmap.set (R m0) Vundef ls).
- assert (UNDEFS: forall ofs ty, In (S (Local ofs ty)) res -> ls1 (S (Local ofs ty)) = Vundef).
- intros. unfold ls1; rewrite Locmap.gso. auto. red; auto.
- generalize (IHres b (Locmap.set (R m0) Vundef ls) m ACC UNDEFS).
- intros [ls2 [EX2 [RES2 OTHER2]]].
- exists ls2. split.
- eapply exec_trans. apply exec_one. apply exec_Bop.
- simpl; reflexivity. eexact EX2. traceEq.
- split. intros. case (In_dec Loc.eq l res); intro.
- apply RES2; auto.
- rewrite OTHER2. elim H1; intro.
- subst l. apply Locmap.gss.
- contradiction.
- apply loc_acceptable_notin_notin; auto.
- intros. rewrite OTHER2. apply Locmap.gso.
- apply Loc.diff_sym; tauto. tauto.
- (* a is a stack location *)
- assert (UNDEFS: forall ofs ty, In (S (Local ofs ty)) res -> ls (S (Local ofs ty)) = Vundef).
- intros. apply H0. tauto.
- generalize (IHres b ls m ACC UNDEFS).
- intros [ls2 [EX2 [RES2 OTHER2]]].
- exists ls2. split. assumption.
- split. intros. case (In_dec Loc.eq l res); intro.
auto.
- rewrite OTHER2. elim H1; intro.
- subst l. generalize (H (S s) (in_eq _ _)).
- unfold loc_acceptable; destruct s; intuition auto.
- contradiction.
- apply loc_acceptable_notin_notin; auto.
- intros. apply OTHER2. tauto.
-Qed.
-
-Lemma add_entry_correct:
- forall sig params undefs s ls m,
- List.length params = List.length sig.(sig_args) ->
- Loc.norepet params ->
- locs_acceptable params ->
- Loc.disjoint params undefs ->
- locs_acceptable undefs ->
- (forall ofs ty, ls (S (Local ofs ty)) = Vundef) ->
- exists ls',
- exec_block ge sp (add_entry sig params undefs s) ls m E0 (Cont s) ls' m /\
- List.map ls' params = List.map ls (loc_parameters sig) /\
- (forall l, In l undefs -> ls' l = Vundef).
-Proof.
- intros.
- assert (List.length (loc_parameters sig) = List.length params).
- unfold loc_parameters. rewrite list_length_map.
- rewrite loc_arguments_length. auto.
- assert (DISJ: Loc.disjoint params temporaries).
- apply locs_acceptable_disj_temporaries; auto.
- generalize (parallel_move_correct _ _ (add_undefs undefs (Bgoto s))
- ls m H5
- (no_overlap_parameters _ _ H1)
- H0 (loc_parameters_not_temporaries sig) DISJ).
- intros [ls1 [EX1 [RES1 [TMP1 OTHER1]]]].
- assert (forall ofs ty, In (S (Local ofs ty)) undefs -> ls1 (S (Local ofs ty)) = Vundef).
- intros. rewrite OTHER1. auto. apply Loc.disjoint_notin with undefs.
- apply Loc.disjoint_sym. auto. auto.
- simpl; tauto.
- generalize (add_undefs_correct undefs (Bgoto s) ls1 m H3 H6).
- intros [ls2 [EX2 [RES2 OTHER2]]].
- exists ls2.
- split. apply exec_Bgoto. unfold add_entry.
- eapply exec_trans. eexact EX1. eexact EX2. traceEq.
- split. rewrite <- RES1. apply list_map_exten.
- intros. symmetry. apply OTHER2. eapply Loc.disjoint_notin; eauto.
- exact RES2.
-Qed.
-
-Lemma add_return_correct:
- forall sig optarg ls m,
- exists ls',
- exec_block ge sp (add_return sig optarg) ls m E0 Return ls' m /\
- match optarg with
- | Some arg => ls' (R (loc_result sig)) = ls arg
- | None => ls' (R (loc_result sig)) = Vundef
- end.
-Proof.
- intros. unfold add_return.
- destruct optarg.
- generalize (add_reload_correct l (loc_result sig) Breturn ls m).
- intros [ls1 [EX1 [RES1 OTH1]]].
- exists ls1.
- split. apply exec_Breturn. assumption. assumption.
- exists (Locmap.set (R (loc_result sig)) Vundef ls).
- split. apply exec_Breturn. apply exec_one.
- apply exec_Bop. reflexivity. apply Locmap.gss.
-Qed.
-
-End LTL_CONSTRUCTORS.
-
-(** * Exploitation of the typing hypothesis *)
-
-(** Register allocation is applied to RTL code that passed type inference
- (see file [RTLtyping]), and therefore is well-typed in the type system
- of [RTLtyping]. We exploit this hypothesis to obtain information on
- the number of arguments to operations, addressing modes and conditions. *)
-
-Remark length_type_of_condition:
- forall (c: condition), (List.length (type_of_condition c) <= 3)%nat.
-Proof.
- destruct c; unfold type_of_condition; simpl; omega.
-Qed.
-
-Remark length_type_of_operation:
- forall (op: operation), (List.length (fst (type_of_operation op)) <= 3)%nat.
-Proof.
- destruct op; unfold type_of_operation; simpl; try omega.
- apply length_type_of_condition.
-Qed.
-
-Remark length_type_of_addressing:
- forall (addr: addressing), (List.length (type_of_addressing addr) <= 2)%nat.
-Proof.
- destruct addr; unfold type_of_addressing; simpl; omega.
Qed.
-Lemma length_op_args:
- forall (env: regenv) (op: operation) (args: list reg) (res: reg),
- (List.map env args, env res) = type_of_operation op ->
- (List.length args <= 3)%nat.
-Proof.
- intros. rewrite <- (list_length_map env).
- generalize (length_type_of_operation op).
- rewrite <- H. simpl. auto.
-Qed.
-
-Lemma length_addr_args:
- forall (env: regenv) (addr: addressing) (args: list reg),
- List.map env args = type_of_addressing addr ->
- (List.length args <= 2)%nat.
-Proof.
- intros. rewrite <- (list_length_map env).
- rewrite H. apply length_type_of_addressing.
-Qed.
-
-Lemma length_cond_args:
- forall (env: regenv) (cond: condition) (args: list reg),
- List.map env args = type_of_condition cond ->
- (List.length args <= 3)%nat.
-Proof.
- intros. rewrite <- (list_length_map env).
- rewrite H. apply length_type_of_condition.
-Qed.
+End AGREE.
(** * Preservation of semantics *)
@@ -1176,7 +477,7 @@ Section PRESERVATION.
Variable prog: RTL.program.
Variable tprog: LTL.program.
-Hypothesis TRANSF: transf_program prog = Some tprog.
+Hypothesis TRANSF: transf_program prog = OK tprog.
Let ge := Genv.globalenv prog.
Let tge := Genv.globalenv tprog.
@@ -1193,740 +494,460 @@ Lemma functions_translated:
forall (v: val) (f: RTL.fundef),
Genv.find_funct ge v = Some f ->
exists tf,
- Genv.find_funct tge v = Some tf /\ transf_fundef f = Some tf.
-Proof.
- intros.
- generalize
- (Genv.find_funct_transf_partial transf_fundef TRANSF H).
- case (transf_fundef f).
- intros tf [A B]. exists tf. tauto.
- intros [A B]. elim B. reflexivity.
-Qed.
+ Genv.find_funct tge v = Some tf /\ transf_fundef f = OK tf.
+Proof (Genv.find_funct_transf_partial transf_fundef TRANSF).
Lemma function_ptr_translated:
- forall (b: Values.block) (f: RTL.fundef),
+ forall (b: block) (f: RTL.fundef),
Genv.find_funct_ptr ge b = Some f ->
exists tf,
- Genv.find_funct_ptr tge b = Some tf /\ transf_fundef f = Some tf.
-Proof.
- intros.
- generalize
- (Genv.find_funct_ptr_transf_partial transf_fundef TRANSF H).
- case (transf_fundef f).
- intros tf [A B]. exists tf. tauto.
- intros [A B]. elim B. reflexivity.
-Qed.
+ Genv.find_funct_ptr tge b = Some tf /\ transf_fundef f = OK tf.
+Proof (Genv.find_funct_ptr_transf_partial transf_fundef TRANSF).
Lemma sig_function_translated:
forall f tf,
- transf_fundef f = Some tf ->
+ transf_fundef f = OK tf ->
LTL.funsig tf = RTL.funsig f.
Proof.
- intros f tf. destruct f; simpl.
+ intros f tf. destruct f; simpl.
unfold transf_function.
destruct (type_function f).
destruct (analyze f).
- destruct (regalloc f t).
- intro EQ; injection EQ; intro EQ1; rewrite <- EQ1; simpl; auto.
- congruence. congruence. congruence.
- intro EQ; inversion EQ; subst tf. reflexivity.
-Qed.
-
-Lemma entrypoint_function_translated:
- forall f tf,
- transf_function f = Some tf ->
- tf.(LTL.fn_entrypoint) = f.(RTL.fn_nextpc).
-Proof.
- intros f tf. unfold transf_function.
- destruct (type_function f).
- destruct (analyze f).
- destruct (regalloc f t).
- intro EQ; injection EQ; intro EQ1; rewrite <- EQ1; simpl; auto.
- intros; discriminate.
- intros; discriminate.
- intros; discriminate.
+ destruct (regalloc f t).
+ intro. monadInv H. inv EQ. auto.
+ simpl; congruence. simpl; congruence. simpl; congruence.
+ intro EQ; inv EQ. auto.
Qed.
(** The proof of semantic preservation is a simulation argument
based on diagrams of the following form:
<<
- pc, rs, m ------------------- pc, ls, m
- | |
- | |
- v v
- pc', rs', m' ---------------- Cont pc', ls', m'
+ st1 --------------- st2
+ | |
+ t| |t
+ | |
+ v v
+ st1'--------------- st2'
>>
Hypotheses: the left vertical arrow represents a transition in the
- original RTL code. The top horizontal bar expresses agreement between
- [rs] and [ls] over the pseudo-registers live before the RTL instruction
- at [pc].
+ original RTL code. The top horizontal bar is the [match_states]
+ relation defined below. It implies agreement between
+ the RTL register map [rs] and the LTL location map [ls]
+ over the pseudo-registers live before the RTL instruction at [pc].
- Conclusions: the right vertical arrow is an [exec_blocks] transition
+ Conclusions: the right vertical arrow is an [exec_instrs] transition
in the LTL code generated by translation of the current function.
- The bottom horizontal bar expresses agreement between [rs'] and [ls']
- over the pseudo-registers live after the RTL instruction at [pc]
- (which implies agreement over the pseudo-registers live before
- the instruction at [pc']).
-
- We capture these diagrams in the following propositions parameterized
- by the transition in the original RTL code (the left arrow).
+ The bottom horizontal bar is the [match_states] relation.
*)
-Definition exec_instr_prop
- (c: RTL.code) (sp: val)
- (pc: node) (rs: regset) (m: mem) (t: trace)
- (pc': node) (rs': regset) (m': mem) : Prop :=
- forall f env live assign ls
- (CF: c = f.(RTL.fn_code))
- (WT: wt_function f env)
- (ASG: regalloc f live (live0 f live) env = Some assign)
- (AG: agree assign (transfer f pc live!!pc) rs ls),
- let tc := PTree.map (transf_instr f live assign) c in
- exists ls',
- exec_blocks tge tc sp pc ls m t (Cont pc') ls' m' /\
- agree assign live!!pc rs' ls'.
-
-Definition exec_instrs_prop
- (c: RTL.code) (sp: val)
- (pc: node) (rs: regset) (m: mem) (t: trace)
- (pc': node) (rs': regset) (m': mem) : Prop :=
- forall f env live assign ls,
- forall (CF: c = f.(RTL.fn_code))
- (WT: wt_function f env)
- (ANL: analyze f = Some live)
- (ASG: regalloc f live (live0 f live) env = Some assign)
- (AG: agree assign (transfer f pc live!!pc) rs ls)
- (VALIDPC': c!pc' <> None),
- let tc := PTree.map (transf_instr f live assign) c in
- exists ls',
- exec_blocks tge tc sp pc ls m t (Cont pc') ls' m' /\
- agree assign (transfer f pc' live!!pc') rs' ls'.
-
-Definition exec_function_prop
- (f: RTL.fundef) (args: list val) (m: mem)
- (t: trace) (res: val) (m': mem) : Prop :=
- forall ls tf,
- transf_fundef f = Some tf ->
- List.map ls (Conventions.loc_arguments (funsig tf)) = args ->
- exists ls',
- LTL.exec_function tge tf ls m t ls' m' /\
- ls' (R (Conventions.loc_result (funsig tf))) = res.
-
-(** The simulation proof is by structural induction over the RTL evaluation
- derivation. We prove each case of the proof as a separate lemma.
- There is one lemma for each RTL evaluation rule. Each lemma concludes
- one of the [exec_*_prop] predicates, and takes the induction hypotheses
- (if any) as hypotheses also expressed with the [exec_*_prop] predicates.
-*)
+Inductive match_stackframes: list RTL.stackframe -> list LTL.stackframe -> signature -> Prop :=
+ | match_stackframes_nil: forall ty_args,
+ match_stackframes nil nil (mksignature ty_args (Some Tint))
+ | match_stackframes_cons:
+ forall s ts sig res f sp pc rs ls env live assign,
+ match_stackframes s ts (RTL.fn_sig f) ->
+ wt_function f env ->
+ analyze f = Some live ->
+ regalloc f live (live0 f live) env = Some assign ->
+ (forall rv ls1,
+ (forall l, Loc.notin l destroyed_at_call -> loc_acceptable l -> ls1 l = ls l) ->
+ Val.lessdef rv (ls1 (R (loc_result sig))) ->
+ agree assign (transfer f pc live!!pc)
+ (rs#res <- rv)
+ (Locmap.set (assign res) (ls1 (R (loc_result sig))) ls1)) ->
+ match_stackframes
+ (RTL.Stackframe res (RTL.fn_code f) sp pc rs :: s)
+ (LTL.Stackframe (assign res) (transf_fun f live assign) sp ls pc :: ts)
+ sig.
+
+Inductive match_states: RTL.state -> LTL.state -> Prop :=
+ | match_states_intro:
+ forall s f sp pc rs m ts ls tm live assign env
+ (STACKS: match_stackframes s ts (RTL.fn_sig f))
+ (WT: wt_function f env)
+ (ANL: analyze f = Some live)
+ (ASG: regalloc f live (live0 f live) env = Some assign)
+ (AG: agree assign (transfer f pc live!!pc) rs ls)
+ (MMD: Mem.lessdef m tm),
+ match_states (RTL.State s (RTL.fn_code f) sp pc rs m)
+ (LTL.State ts (transf_fun f live assign) sp pc ls tm)
+ | match_states_call:
+ forall s f args m ts tf ls tm,
+ match_stackframes s ts (RTL.funsig f) ->
+ transf_fundef f = OK tf ->
+ Val.lessdef_list args (List.map ls (loc_arguments (funsig tf))) ->
+ Mem.lessdef m tm ->
+ (forall l, Loc.notin l destroyed_at_call -> loc_acceptable l -> ls l = parent_locset ts l) ->
+ match_states (RTL.Callstate s f args m)
+ (LTL.Callstate ts tf ls tm)
+ | match_states_return:
+ forall s v m ts sig ls tm,
+ match_stackframes s ts sig ->
+ Val.lessdef v (ls (R (loc_result sig))) ->
+ Mem.lessdef m tm ->
+ (forall l, Loc.notin l destroyed_at_call -> loc_acceptable l -> ls l = parent_locset ts l) ->
+ match_states (RTL.Returnstate s v m)
+ (LTL.Returnstate ts sig ls tm).
+
+Remark match_stackframes_change:
+ forall s ts sig,
+ match_stackframes s ts sig ->
+ forall sig',
+ sig_res sig' = sig_res sig ->
+ match_stackframes s ts sig'.
+Proof.
+ induction 1; intros.
+ destruct sig'. simpl in H; inv H. constructor.
+ assert (loc_result sig' = loc_result sig).
+ unfold loc_result. rewrite H4; auto.
+ econstructor; eauto.
+ rewrite H5. auto.
+Qed.
+
+(** The simulation proof is by case analysis over the RTL transition
+ taken in the source program. *)
Ltac CleanupHyps :=
match goal with
+ | H: (match_states _ _) |- _ =>
+ inv H; CleanupHyps
| H1: (PTree.get _ _ = Some _),
- H2: (_ = RTL.fn_code _),
- H3: (agree _ (transfer _ _ _) _ _) |- _ =>
- unfold transfer in H3; rewrite <- H2 in H3; rewrite H1 in H3;
- simpl in H3;
- CleanupHyps
+ H2: (agree _ (transfer _ _ _) _ _) |- _ =>
+ unfold transfer in H2; rewrite H1 in H2; simpl in H2; CleanupHyps
+ | _ => idtac
+ end.
+
+Ltac WellTypedHyp :=
+ match goal with
| H1: (PTree.get _ _ = Some _),
- H2: (_ = RTL.fn_code _),
- H3: (wt_function _ _) |- _ =>
- let H := fresh in
+ H2: (wt_function _ _) |- _ =>
let R := fresh "WTI" in (
- generalize (wt_instrs _ _ H3); intro H;
- rewrite <- H2 in H; generalize (H _ _ H1);
- intro R; clear H; clear H3);
- CleanupHyps
+ generalize (wt_instrs _ _ H2 _ _ H1); intro R)
| _ => idtac
end.
-Ltac CleanupGoal :=
+Ltac TranslInstr :=
match goal with
- | H1: (PTree.get _ _ = Some _) |- _ =>
- eapply exec_blocks_one;
- [rewrite PTree.gmap; rewrite H1;
- unfold option_map; unfold transf_instr; reflexivity
- |idtac]
+ | H: (PTree.get _ _ = Some _) |- _ =>
+ simpl; rewrite PTree.gmap; rewrite H; simpl; auto
end.
-Lemma transl_Inop_correct:
- forall (c : PTree.t instruction) (sp: val) (pc : positive)
- (rs : regset) (m : mem) (pc' : RTL.node),
- c ! pc = Some (Inop pc') ->
- exec_instr_prop c sp pc rs m E0 pc' rs m.
+Ltac MatchStates :=
+ match goal with
+ | |- match_states (RTL.State _ _ _ _ _ _) (LTL.State _ _ _ _ _ _) =>
+ eapply match_states_intro; eauto; MatchStates
+ | H: (PTree.get ?pc _ = Some _) |- agree _ _ _ _ =>
+ eapply agree_succ with (n := pc); eauto; MatchStates
+ | H: (PTree.get _ _ = Some _) |- In _ (RTL.successors _ _) =>
+ unfold RTL.successors; rewrite H; auto with coqlib
+ | _ => idtac
+ end.
+
+
+Lemma transl_find_function:
+ forall ros f args lv rs ls alloc,
+ RTL.find_function ge ros rs = Some f ->
+ agree alloc (reg_list_live args (reg_sum_live ros lv)) rs ls ->
+ exists tf,
+ LTL.find_function tge (sum_left_map alloc ros) ls = Some tf /\
+ transf_fundef f = OK tf.
Proof.
- intros; red; intros; CleanupHyps.
- exists ls. split.
- CleanupGoal. apply exec_Bgoto. apply exec_refl.
- assumption.
+ intros; destruct ros; simpl in *.
+ assert (Val.lessdef (rs#r) (ls (alloc r))).
+ eapply agree_eval_reg. eapply agree_reg_list_live; eauto.
+ inv H1. apply functions_translated. auto.
+ exploit Genv.find_funct_inv; eauto. intros [b EQ]. congruence.
+ rewrite symbols_preserved. destruct (Genv.find_symbol ge i).
+ apply function_ptr_translated. auto. discriminate.
Qed.
-Lemma transl_Iop_correct:
- forall (c : PTree.t instruction) (sp: val) (pc : positive)
- (rs : Regmap.t val) (m : mem) (op : operation) (args : list reg)
- (res : reg) (pc' : RTL.node) (v: val),
- c ! pc = Some (Iop op args res pc') ->
- eval_operation ge sp op (rs ## args) = Some v ->
- exec_instr_prop c sp pc rs m E0 pc' (rs # res <- v) m.
+Theorem transl_step_correct:
+ forall s1 t s2, RTL.step ge s1 t s2 ->
+ forall s1', match_states s1 s1' ->
+ exists s2', LTL.step tge s1' t s2' /\ match_states s2 s2'.
Proof.
- intros; red; intros; CleanupHyps.
+ induction 1; intros; CleanupHyps; WellTypedHyp.
+
+ (* Inop *)
+ econstructor; split.
+ eapply exec_Lnop. TranslInstr. MatchStates.
+
+ (* Iop *)
+ generalize (PTree.gmap (transf_instr f live assign) pc (RTL.fn_code f)).
+ rewrite H. simpl.
caseEq (Regset.mem res live!!pc); intro LV;
rewrite LV in AG.
generalize (Regset.mem_2 _ _ LV). intro LV'.
- assert (LL: (List.length (List.map assign args) <= 3)%nat).
- rewrite list_length_map.
- inversion WTI. simpl; omega. simpl; omega.
- eapply length_op_args. eauto.
- assert (DISJ: Loc.disjoint (List.map assign args) temporaries).
- eapply regalloc_disj_temporaries; eauto.
- assert (eval_operation tge sp op (map ls (map assign args)) = Some v).
- replace (map ls (map assign args)) with rs##args.
- rewrite (eval_operation_preserved symbols_preserved). assumption.
- symmetry. eapply agree_eval_regs; eauto.
- generalize (add_op_correct tge sp op
- (List.map assign args) (assign res)
- pc' ls m v LL DISJ H1).
- intros [ls' [EX [RES OTHER]]].
- exists ls'. split.
- CleanupGoal. rewrite LV. exact EX.
- rewrite CF in H.
generalize (regalloc_correct_1 f env live _ _ _ _ ASG H).
- unfold correct_alloc_instr.
+ unfold correct_alloc_instr, is_redundant_move.
caseEq (is_move_operation op args).
(* Special case for moves *)
intros arg IMO CORR.
generalize (is_move_operation_correct _ _ IMO).
intros [EQ1 EQ2]. subst op; subst args.
- injection H0; intro. rewrite <- H2.
- apply agree_move_live with f env live ls; auto.
- rewrite RES. rewrite <- H2. symmetry. eapply agree_eval_reg.
- simpl in AG. eexact AG.
+ injection H0; intro.
+ destruct (Loc.eq (assign arg) (assign res)); intro CODE.
+ (* sub-case: redundant move *)
+ econstructor; split. eapply exec_Lnop; eauto.
+ MatchStates.
+ rewrite <- H1. eapply agree_redundant_move_live; eauto.
+ (* sub-case: non-redundant move *)
+ econstructor; split. eapply exec_Lop; eauto. simpl. eauto.
+ MatchStates.
+ rewrite <- H1. eapply agree_move_live; eauto.
(* Not a move *)
- intros INMO CORR.
- apply agree_assign_live with f env live ls; auto.
+ intros INMO CORR CODE.
+ assert (exists v1,
+ eval_operation tge sp op (map ls (map assign args)) tm = Some v1
+ /\ Val.lessdef v v1).
+ apply eval_operation_lessdef with m (rs##args); auto.
+ eapply agree_eval_regs; eauto.
+ rewrite (eval_operation_preserved symbols_preserved). assumption.
+ destruct H1 as [v1 [EV VMD]].
+ econstructor; split. eapply exec_Lop; eauto.
+ MatchStates.
+ apply agree_assign_live with f env live; auto.
eapply agree_reg_list_live; eauto.
(* Result is not live, instruction turned into a nop *)
- exists ls. split.
- CleanupGoal. rewrite LV.
- apply exec_Bgoto; apply exec_refl.
- apply agree_assign_dead; auto.
+ intro CODE. econstructor; split. eapply exec_Lnop; eauto.
+ MatchStates. apply agree_assign_dead; auto.
red; intro. exploit Regset.mem_1; eauto. congruence.
-Qed.
-Lemma transl_Iload_correct:
- forall (c : PTree.t instruction) (sp: val) (pc : positive)
- (rs : Regmap.t val) (m : mem) (chunk : memory_chunk)
- (addr : addressing) (args : list reg) (dst : reg) (pc' : RTL.node)
- (a v : val),
- c ! pc = Some (Iload chunk addr args dst pc') ->
- eval_addressing ge sp addr rs ## args = Some a ->
- loadv chunk m a = Some v ->
- exec_instr_prop c sp pc rs m E0 pc' rs # dst <- v m.
-Proof.
- intros; red; intros; CleanupHyps.
+ (* Iload *)
caseEq (Regset.mem dst live!!pc); intro LV;
rewrite LV in AG.
(* dst is live *)
exploit Regset.mem_2; eauto. intro LV'.
- assert (LL: (List.length (List.map assign args) <= 2)%nat).
- rewrite list_length_map.
- inversion WTI.
- eapply length_addr_args. eauto.
- assert (DISJ: Loc.disjoint (List.map assign args) temporaries).
- eapply regalloc_disj_temporaries; eauto.
- assert (EADDR:
- eval_addressing tge sp addr (map ls (map assign args)) = Some a).
- rewrite <- H0.
- replace (rs##args) with (map ls (map assign args)).
- apply eval_addressing_preserved. exact symbols_preserved.
+ assert (exists a',
+ eval_addressing tge sp addr (map ls (map assign args)) = Some a'
+ /\ Val.lessdef a a').
+ apply eval_addressing_lessdef with (rs##args).
eapply agree_eval_regs; eauto.
- generalize (add_load_correct tge sp chunk addr
- (List.map assign args) (assign dst)
- pc' ls m _ _ LL DISJ EADDR H1).
- intros [ls' [EX [RES OTHER]]].
- exists ls'. split. CleanupGoal. rewrite LV. exact EX.
- rewrite CF in H.
+ rewrite <- H0. apply eval_addressing_preserved. exact symbols_preserved.
+ destruct H2 as [a' [EVAL VMD]].
+ exploit Mem.loadv_lessdef; eauto.
+ intros [v' [LOADV VMD2]].
+ econstructor; split.
+ eapply exec_Lload; eauto. TranslInstr. rewrite LV; auto.
generalize (regalloc_correct_1 f env live _ _ _ _ ASG H).
unfold correct_alloc_instr. intro CORR.
+ MatchStates.
eapply agree_assign_live; eauto.
eapply agree_reg_list_live; eauto.
(* dst is dead *)
- exists ls. split.
- CleanupGoal. rewrite LV.
- apply exec_Bgoto; apply exec_refl.
- apply agree_assign_dead; auto.
+ econstructor; split.
+ eapply exec_Lnop. TranslInstr. rewrite LV; auto.
+ MatchStates. apply agree_assign_dead; auto.
red; intro; exploit Regset.mem_1; eauto. congruence.
-Qed.
-Lemma transl_Istore_correct:
- forall (c : PTree.t instruction) (sp: val) (pc : positive)
- (rs : Regmap.t val) (m : mem) (chunk : memory_chunk)
- (addr : addressing) (args : list reg) (src : reg) (pc' : RTL.node)
- (a : val) (m' : mem),
- c ! pc = Some (Istore chunk addr args src pc') ->
- eval_addressing ge sp addr rs ## args = Some a ->
- storev chunk m a rs # src = Some m' ->
- exec_instr_prop c sp pc rs m E0 pc' rs m'.
-Proof.
- intros; red; intros; CleanupHyps.
- assert (LL: (List.length (List.map assign args) <= 2)%nat).
- rewrite list_length_map.
- inversion WTI.
- eapply length_addr_args. eauto.
- assert (DISJ: Loc.disjoint (List.map assign args) temporaries).
- eapply regalloc_disj_temporaries; eauto.
- assert (SRC: Loc.notin (assign src) temporaries).
- eapply regalloc_not_temporary; eauto.
- assert (EADDR:
- eval_addressing tge sp addr (map ls (map assign args)) = Some a).
- rewrite <- H0.
- replace (rs##args) with (map ls (map assign args)).
- apply eval_addressing_preserved. exact symbols_preserved.
+ (* Istore *)
+ assert (exists a',
+ eval_addressing tge sp addr (map ls (map assign args)) = Some a'
+ /\ Val.lessdef a a').
+ apply eval_addressing_lessdef with (rs##args).
eapply agree_eval_regs; eauto.
- assert (ESRC: ls (assign src) = rs#src).
+ rewrite <- H0. apply eval_addressing_preserved. exact symbols_preserved.
+ destruct H2 as [a' [EVAL VMD]].
+ assert (ESRC: Val.lessdef rs#src (ls (assign src))).
eapply agree_eval_reg. eapply agree_reg_list_live. eauto.
- rewrite <- ESRC in H1.
- generalize (add_store_correct tge sp chunk addr
- (List.map assign args) (assign src)
- pc' ls m m' a LL DISJ SRC EADDR H1).
- intros [ls' [EX RES]].
- exists ls'. split. CleanupGoal. exact EX.
- rewrite CF in H.
- generalize (regalloc_correct_1 f env live _ _ _ _ ASG H).
- unfold correct_alloc_instr. intro CORR.
- eapply agree_exten. eauto.
- eapply agree_reg_live. eapply agree_reg_list_live. eauto.
- assumption.
-Qed.
-
-Lemma transl_Icall_correct:
- forall (c : PTree.t instruction) (sp: val) (pc : positive)
- (rs : regset) (m : mem) (sig : signature) (ros : reg + ident)
- (args : list reg) (res : reg) (pc' : RTL.node)
- (f : RTL.fundef) (vres : val) (m' : mem) (t: trace),
- c ! pc = Some (Icall sig ros args res pc') ->
- RTL.find_function ge ros rs = Some f ->
- RTL.funsig f = sig ->
- RTL.exec_function ge f (rs##args) m t vres m' ->
- exec_function_prop f (rs##args) m t vres m' ->
- exec_instr_prop c sp pc rs m t pc' (rs#res <- vres) m'.
-Proof.
- intros; red; intros; CleanupHyps.
- set (los := sum_left_map assign ros).
- assert (FIND: exists tf,
- find_function2 tge los ls = Some tf /\
- transf_fundef f = Some tf).
- unfold los. destruct ros; simpl; simpl in H0.
- apply functions_translated.
- replace (ls (assign r)) with rs#r. assumption.
- simpl in AG. symmetry; eapply agree_eval_reg.
- eapply agree_reg_list_live; eauto.
- rewrite symbols_preserved. destruct (Genv.find_symbol ge i).
- apply function_ptr_translated. auto.
- discriminate.
- elim FIND; intros tf [AFIND TRF]; clear FIND.
- assert (ASIG: sig = funsig tf).
- rewrite (sig_function_translated _ _ TRF). auto.
- generalize (fun ls => H3 ls tf TRF); intro AEXECF.
- assert (AVARGS: List.map ls (List.map assign args) = rs##args).
- eapply agree_eval_regs; eauto.
- assert (ALARGS: List.length (List.map assign args) =
- List.length sig.(sig_args)).
- inversion WTI. rewrite <- H10.
- repeat rewrite list_length_map. auto.
- assert (AACCEPT: locs_acceptable (List.map assign args)).
- eapply regsalloc_acceptable; eauto.
- rewrite CF in H.
- generalize (regalloc_correct_1 f0 env live _ _ _ _ ASG H).
- unfold correct_alloc_instr. intros [CORR1 CORR2].
- assert (ARES: loc_acceptable (assign res)).
- eapply regalloc_acceptable; eauto.
- generalize (add_call_correct tge sp tf _ _ _ _ _ _ _ _ _ pc' _
- AEXECF AFIND ASIG AVARGS ALARGS
- AACCEPT ARES).
- intros [ls' [EX [RES OTHER]]].
- exists ls'.
- split. rewrite CF. CleanupGoal. exact EX.
- simpl. eapply agree_call; eauto.
-Qed.
-
-Lemma transl_Ialloc_correct:
- forall (c : PTree.t instruction) (sp: val) (pc : positive)
- (rs : Regmap.t val) (m : mem) (pc': RTL.node) (arg res: reg)
- (sz: int) (m': mem) (b: Values.block),
- c ! pc = Some (Ialloc arg res pc') ->
- rs#arg = Vint sz ->
- Mem.alloc m 0 (Int.signed sz) = (m', b) ->
- exec_instr_prop c sp pc rs m E0 pc' (rs # res <- (Vptr b Int.zero)) m'.
-Proof.
- intros; red; intros; CleanupHyps.
- assert (SZ: ls (assign arg) = Vint sz).
+ assert (exists tm', storev chunk tm a' (ls (assign src)) = Some tm'
+ /\ Mem.lessdef m' tm').
+ eapply Mem.storev_lessdef; eauto.
+ destruct H2 as [m1' [STORE MMD']].
+ econstructor; split.
+ eapply exec_Lstore; eauto. TranslInstr.
+ MatchStates. eapply agree_reg_live. eapply agree_reg_list_live. eauto.
+
+ (* Icall *)
+ exploit transl_find_function; eauto. intros [tf [TFIND TF]].
+ generalize (regalloc_correct_1 f0 env live _ _ _ _ ASG H). unfold correct_alloc_instr. intros [CORR1 CORR2].
+ exploit (parmov_spec ls (map assign args)
+ (loc_arguments (RTL.funsig f))).
+ apply loc_arguments_norepet.
+ rewrite loc_arguments_length. inv WTI.
+ rewrite <- H7. repeat rewrite list_length_map. auto.
+ intros [PM1 PM2].
+ econstructor; split.
+ eapply exec_Lcall; eauto. TranslInstr.
+ rewrite (sig_function_translated _ _ TF). eauto.
+ rewrite (sig_function_translated _ _ TF).
+ econstructor; eauto.
+ econstructor; eauto.
+ intros. eapply agree_succ with (n := pc); eauto.
+ unfold RTL.successors; rewrite H; auto with coqlib.
+ eapply agree_call with (ls := ls); eauto.
+ rewrite Locmap.gss. auto.
+ intros. rewrite Locmap.gso. rewrite H1; auto. apply PM2; auto.
+ eapply arguments_not_preserved; eauto. apply Loc.diff_sym; auto.
+ rewrite (sig_function_translated _ _ TF).
+ change Regset.elt with reg in PM1.
+ rewrite PM1. eapply agree_eval_regs; eauto.
+
+ (* Itailcall *)
+ exploit transl_find_function; eauto. intros [tf [TFIND TF]].
+ exploit (parmov_spec ls (map assign args)
+ (loc_arguments (RTL.funsig f))).
+ apply loc_arguments_norepet.
+ rewrite loc_arguments_length. inv WTI.
+ rewrite <- H6. repeat rewrite list_length_map. auto.
+ intros [PM1 PM2].
+ econstructor; split.
+ eapply exec_Ltailcall; eauto. TranslInstr.
+ rewrite (sig_function_translated _ _ TF). eauto.
+ rewrite (sig_function_translated _ _ TF).
+ econstructor; eauto.
+ apply match_stackframes_change with (RTL.fn_sig f0); auto.
+ inv WTI. auto.
+ rewrite (sig_function_translated _ _ TF).
+ rewrite return_regs_arguments.
+ change Regset.elt with reg in PM1.
+ rewrite PM1. eapply agree_eval_regs; eauto.
+ inv WTI; auto.
+ apply free_lessdef; auto.
+ intros. rewrite return_regs_not_destroyed; auto.
+
+ (* Ialloc *)
+ assert (Val.lessdef (Vint sz) (ls (assign arg))).
rewrite <- H0. eapply agree_eval_reg. eauto.
- generalize (add_alloc_correct tge sp (assign arg) (assign res)
- pc' ls m m' sz b SZ H1).
- intros [ls' [EX [RES OTHER]]].
- exists ls'.
- split. CleanupGoal. exact EX.
- rewrite CF in H.
+ inversion H2. subst v.
+ pose (ls1 := Locmap.set (R loc_alloc_argument) (ls (assign arg)) ls).
+ pose (ls2 := Locmap.set (R loc_alloc_result) (Vptr b Int.zero) ls1).
+ pose (ls3 := Locmap.set (assign res) (ls2 (R loc_alloc_result)) ls2).
+ caseEq (alloc tm 0 (Int.signed sz)). intros tm' b1 ALLOC1.
+ exploit Mem.alloc_lessdef; eauto. intros [EQ MMD1]. subst b1.
+ exists (State ts (transf_fun f live assign) sp pc' ls3 tm'); split.
+ unfold ls3, ls2, ls1. eapply exec_Lalloc; eauto. TranslInstr.
generalize (regalloc_correct_1 f env live _ _ _ _ ASG H).
unfold correct_alloc_instr. intros [CORR1 CORR2].
- eapply agree_call with (args := arg :: nil) (ros := inr reg 1%positive) (ls := ls) (ls' := ls'); eauto.
- intros. apply OTHER.
- eapply Loc.in_notin_diff; eauto.
- unfold loc_alloc_argument, destroyed_at_call; simpl; tauto.
- eapply Loc.in_notin_diff; eauto.
+ MatchStates.
+ eapply agree_call with (args := arg :: nil) (ros := inr reg 1%positive) (ls := ls); eauto.
+ unfold ls3; rewrite Locmap.gss.
+ unfold ls2; rewrite Locmap.gss. auto.
+ intros. unfold ls3; rewrite Locmap.gso.
+ unfold ls2; rewrite Locmap.gso.
+ unfold ls1; apply Locmap.gso.
+ apply Loc.diff_sym. eapply Loc.in_notin_diff; eauto.
unfold loc_alloc_argument, destroyed_at_call; simpl; tauto.
- auto.
-Qed.
-
-Lemma transl_Icond_true_correct:
- forall (c : PTree.t instruction) (sp: val) (pc : positive)
- (rs : Regmap.t val) (m : mem) (cond : condition) (args : list reg)
- (ifso ifnot : RTL.node),
- c ! pc = Some (Icond cond args ifso ifnot) ->
- eval_condition cond rs ## args = Some true ->
- exec_instr_prop c sp pc rs m E0 ifso rs m.
-Proof.
- intros; red; intros; CleanupHyps.
- assert (LL: (List.length (map assign args) <= 3)%nat).
- rewrite list_length_map. inversion WTI.
- eapply length_cond_args. eauto.
- assert (DISJ: Loc.disjoint (map assign args) temporaries).
- eapply regalloc_disj_temporaries; eauto.
- assert (COND: eval_condition cond (map ls (map assign args)) = Some true).
- replace (map ls (map assign args)) with rs##args. assumption.
- symmetry. eapply agree_eval_regs; eauto.
- generalize (add_cond_correct tge sp _ _ _ ifnot _ m _ _
- LL DISJ COND (refl_equal ifso)).
- intros [ls' [EX OTHER]].
- exists ls'. split.
- CleanupGoal. assumption.
- eapply agree_exten. eauto. eapply agree_reg_list_live. eauto.
- assumption.
-Qed.
-
-Lemma transl_Icond_false_correct:
- forall (c : PTree.t instruction) (sp: val) (pc : positive)
- (rs : Regmap.t val) (m : mem) (cond : condition) (args : list reg)
- (ifso ifnot : RTL.node),
- c ! pc = Some (Icond cond args ifso ifnot) ->
- eval_condition cond rs ## args = Some false ->
- exec_instr_prop c sp pc rs m E0 ifnot rs m.
-Proof.
- intros; red; intros; CleanupHyps.
- assert (LL: (List.length (map assign args) <= 3)%nat).
- rewrite list_length_map. inversion WTI.
- eapply length_cond_args. eauto.
- assert (DISJ: Loc.disjoint (map assign args) temporaries).
- eapply regalloc_disj_temporaries; eauto.
- assert (COND: eval_condition cond (map ls (map assign args)) = Some false).
- replace (map ls (map assign args)) with rs##args. assumption.
- symmetry. eapply agree_eval_regs; eauto.
- generalize (add_cond_correct tge sp _ _ ifso _ _ m _ _
- LL DISJ COND (refl_equal ifnot)).
- intros [ls' [EX OTHER]].
- exists ls'. split.
- CleanupGoal. assumption.
- eapply agree_exten. eauto. eapply agree_reg_list_live. eauto.
- assumption.
-Qed.
-
-Lemma transl_refl_correct:
- forall (c : RTL.code) (sp: val) (pc : RTL.node) (rs : regset)
- (m : mem), exec_instrs_prop c sp pc rs m E0 pc rs m.
-Proof.
- intros; red; intros.
- exists ls. split. apply exec_blocks_refl. assumption.
-Qed.
-
-Lemma transl_one_correct:
- forall (c : RTL.code) (sp: val) (pc : RTL.node) (rs : regset)
- (m : mem) (t: trace) (pc' : RTL.node) (rs' : regset) (m' : mem),
- RTL.exec_instr ge c sp pc rs m t pc' rs' m' ->
- exec_instr_prop c sp pc rs m t pc' rs' m' ->
- exec_instrs_prop c sp pc rs m t pc' rs' m'.
-Proof.
- intros; red; intros.
- generalize (H0 f env live assign ls CF WT ASG AG).
- intros [ls' [EX AG']].
- exists ls'. split.
- exact EX.
- apply agree_increasing with live!!pc.
- apply analyze_correct. auto.
- rewrite <- CF. eapply exec_instr_present; eauto.
- rewrite <- CF. auto.
- eapply RTL.successors_correct.
- rewrite <- CF. eexact H. exact AG'.
-Qed.
-
-Lemma transl_trans_correct:
- forall (c : RTL.code) (sp: val) (pc1 : RTL.node) (rs1 : regset)
- (m1 : mem) (t1: trace) (pc2 : RTL.node) (rs2 : regset) (m2 : mem)
- (t2: trace) (pc3 : RTL.node) (rs3 : regset) (m3 : mem) (t3: trace),
- RTL.exec_instrs ge c sp pc1 rs1 m1 t1 pc2 rs2 m2 ->
- exec_instrs_prop c sp pc1 rs1 m1 t1 pc2 rs2 m2 ->
- RTL.exec_instrs ge c sp pc2 rs2 m2 t2 pc3 rs3 m3 ->
- exec_instrs_prop c sp pc2 rs2 m2 t2 pc3 rs3 m3 ->
- t3 = t1 ** t2 ->
- exec_instrs_prop c sp pc1 rs1 m1 t3 pc3 rs3 m3.
-Proof.
- intros; red; intros.
- assert (VALIDPC2: c!pc2 <> None).
- eapply exec_instrs_present; eauto.
- generalize (H0 f env live assign ls CF WT ANL ASG AG VALIDPC2).
- intros [ls1 [EX1 AG1]].
- generalize (H2 f env live assign ls1 CF WT ANL ASG AG1 VALIDPC').
- intros [ls2 [EX2 AG2]].
- exists ls2. split.
- eapply exec_blocks_trans. eexact EX1. eexact EX2. auto.
- exact AG2.
-Qed.
-
-Remark regset_mem_reg_list_dead:
- forall rl r live,
- Regset.In r (reg_list_dead rl live) ->
- ~(In r rl) /\ Regset.In r live.
-Proof.
- induction rl; simpl; intros.
- tauto.
- elim (IHrl r (reg_dead a live) H). intros.
- assert (a <> r). red; intro; subst r.
- exploit Regset.remove_1; eauto.
- intuition. eapply Regset.remove_3; eauto.
-Qed.
-
-Lemma transf_entrypoint_correct:
- forall f env live assign c ls args sp m,
- wt_function f env ->
- regalloc f live (live0 f live) env = Some assign ->
- c!(RTL.fn_nextpc f) = None ->
- List.map ls (loc_parameters (RTL.fn_sig f)) = args ->
- (forall ofs ty, ls (S (Local ofs ty)) = Vundef) ->
- let tc := transf_entrypoint f live assign c in
- exists ls',
- exec_blocks tge tc sp (RTL.fn_nextpc f) ls m E0
- (Cont (RTL.fn_entrypoint f)) ls' m /\
- agree assign (transfer f (RTL.fn_entrypoint f) live!!(RTL.fn_entrypoint f))
- (init_regs args (RTL.fn_params f)) ls'.
-Proof.
- intros until m.
- unfold transf_entrypoint.
- set (oldentry := RTL.fn_entrypoint f).
- set (newentry := RTL.fn_nextpc f).
- set (params := RTL.fn_params f).
- set (undefs := Regset.elements (reg_list_dead params (transfer f oldentry live!!oldentry))).
- intros.
-
- assert (A1: List.length (List.map assign params) =
- List.length (RTL.fn_sig f).(sig_args)).
- rewrite <- (wt_params _ _ H).
- repeat (rewrite list_length_map). auto.
- assert (A2: Loc.norepet (List.map assign (RTL.fn_params f))).
- eapply regalloc_norepet_norepet; eauto.
- eapply regalloc_correct_2; eauto.
- eapply wt_norepet; eauto.
- assert (A3: locs_acceptable (List.map assign (RTL.fn_params f))).
- eapply regsalloc_acceptable; eauto.
- assert (A4: Loc.disjoint
- (List.map assign (RTL.fn_params f))
- (List.map assign undefs)).
- red. intros ap au INAP INAU.
- generalize (list_in_map_inv _ _ _ INAP).
- intros [p [AP INP]]. clear INAP; subst ap.
- generalize (list_in_map_inv _ _ _ INAU).
- intros [u [AU INU]]. clear INAU; subst au.
- assert (INU': InA Regset.E.eq u undefs).
- rewrite InA_alt. exists u; intuition.
- generalize (Regset.elements_2 _ _ INU'). intro.
- generalize (regset_mem_reg_list_dead _ _ _ H4).
- intros [A B].
- eapply regalloc_noteq_diff; eauto.
- eapply regalloc_correct_3; eauto.
- red; intro; subst u. elim (A INP).
- assert (A5: forall l, In l (List.map assign undefs) -> loc_acceptable l).
- intros.
- generalize (list_in_map_inv _ _ _ H4).
- intros [r [AR INR]]. clear H4; subst l.
- eapply regalloc_acceptable; eauto.
- generalize (add_entry_correct
- tge sp (RTL.fn_sig f)
- (List.map assign (RTL.fn_params f))
- (List.map assign undefs)
- oldentry ls m A1 A2 A3 A4 A5 H3).
- intros [ls1 [EX1 [PARAMS1 UNDEFS1]]].
- exists ls1.
- split. eapply exec_blocks_one.
- rewrite PTree.gss. reflexivity.
- assumption.
- change (transfer f oldentry live!!oldentry)
- with (live0 f live).
- unfold params; eapply agree_parameters; eauto.
- change Regset.elt with reg in PARAMS1.
- rewrite PARAMS1. assumption.
- fold oldentry; fold params. intros.
- apply UNDEFS1. apply in_map.
- unfold undefs.
- change (transfer f oldentry live!!oldentry)
- with (live0 f live).
- exploit Regset.elements_1; eauto.
- rewrite InA_alt. intros [r' [C D]]. hnf in C. subst r'. auto.
-Qed.
-
-Lemma transl_function_correct:
- forall (f : RTL.function) (m m1 : mem) (stk : Values.block)
- (args : list val) (t: trace) (pc : RTL.node) (rs : regset) (m2 : mem)
- (or : option reg) (vres : val),
- alloc m 0 (RTL.fn_stacksize f) = (m1, stk) ->
- RTL.exec_instrs ge (RTL.fn_code f) (Vptr stk Int.zero)
- (RTL.fn_entrypoint f) (init_regs args (fn_params f)) m1 t pc rs m2 ->
- exec_instrs_prop (RTL.fn_code f) (Vptr stk Int.zero)
- (RTL.fn_entrypoint f) (init_regs args (fn_params f)) m1 t pc rs m2 ->
- (RTL.fn_code f) ! pc = Some (Ireturn or) ->
- vres = regmap_optget or Vundef rs ->
- exec_function_prop (Internal f) args m t vres (free m2 stk).
-Proof.
- intros; red; intros until tf.
- unfold transf_fundef, transf_partial_fundef, transf_function.
- caseEq (type_function f).
- intros env TRF.
- caseEq (analyze f).
- intros live ANL.
- change (transfer f (RTL.fn_entrypoint f) live!!(RTL.fn_entrypoint f))
- with (live0 f live).
- caseEq (regalloc f live (live0 f live) env).
- intros alloc ASG.
- set (tc1 := PTree.map (transf_instr f live alloc) (RTL.fn_code f)).
- set (tc2 := transf_entrypoint f live alloc tc1).
- intro EQ; injection EQ; intro TF; clear EQ. intro VARGS.
- generalize (type_function_correct _ _ TRF); intro WTF.
- assert (NEWINSTR: tc1!(RTL.fn_nextpc f) = None).
- unfold tc1; rewrite PTree.gmap. unfold option_map.
- elim (RTL.fn_code_wf f (fn_nextpc f)); intro.
- elim (Plt_ne _ _ H4). auto.
- rewrite H4. auto.
- pose (ls1 := call_regs ls).
- assert (VARGS1: List.map ls1 (loc_parameters (RTL.fn_sig f)) = args).
- replace (RTL.fn_sig f) with (funsig tf).
- rewrite <- VARGS. unfold loc_parameters.
- rewrite list_map_compose. apply list_map_exten.
- intros. symmetry. unfold ls1. eapply call_regs_param_of_arg; eauto.
- rewrite <- TF; reflexivity.
- assert (VUNDEFS: forall (ofs : Z) (ty : typ), ls1 (S (Local ofs ty)) = Vundef).
- intros. reflexivity.
- generalize (transf_entrypoint_correct f env live alloc
- tc1 ls1 args (Vptr stk Int.zero) m1
- WTF ASG NEWINSTR VARGS1 VUNDEFS).
- fold tc2. intros [ls2 [EX2 AGREE2]].
- assert (VALIDPC: f.(RTL.fn_code)!pc <> None). congruence.
- generalize (H1 f env live alloc ls2
- (refl_equal _) WTF ANL ASG AGREE2 VALIDPC).
- fold tc1. intros [ls3 [EX3 AGREE3]].
- generalize (add_return_correct tge (Vptr stk Int.zero) (RTL.fn_sig f)
- (option_map alloc or) ls3 m2).
- intros [ls4 [EX4 RES4]].
- exists ls4.
- (* Execution *)
- split. rewrite <- TF; apply exec_funct_internal with m1; simpl.
- assumption.
- fold ls1.
- eapply exec_blocks_trans. eexact EX2.
- apply exec_blocks_extends with tc1.
- intro p. unfold tc2. unfold transf_entrypoint.
- case (peq p (fn_nextpc f)); intro.
- subst p. right. unfold tc1; rewrite PTree.gmap.
- elim (RTL.fn_code_wf f (fn_nextpc f)); intro.
- elim (Plt_ne _ _ H4); auto. rewrite H4; reflexivity.
- left; apply PTree.gso; auto.
- eapply exec_blocks_trans. eexact EX3.
- eapply exec_blocks_one.
- unfold tc1. rewrite PTree.gmap. rewrite H2. simpl. reflexivity.
- eexact EX4. reflexivity. traceEq.
- destruct or.
- simpl in RES4. simpl in H3.
- rewrite H3. rewrite <- TF; simpl. rewrite RES4.
- eapply agree_eval_reg; eauto.
- unfold transfer in AGREE3; rewrite H2 in AGREE3.
- unfold reg_option_live in AGREE3. eexact AGREE3.
- simpl in RES4. simpl in H3.
- rewrite <- TF; simpl. congruence.
- intros; discriminate.
- intros; discriminate.
- intros; discriminate.
-Qed.
+ apply Loc.diff_sym. eapply Loc.in_notin_diff; eauto.
+ unfold loc_alloc_result, destroyed_at_call; simpl; tauto.
+ apply Loc.diff_sym; auto.
-Lemma transl_external_function_correct:
- forall (ef : external_function) (args : list val) (m : mem)
- (t: trace) (res: val),
- event_match ef args t res ->
- exec_function_prop (External ef) args m t res m.
-Proof.
- intros; red; intros.
- simpl in H0.
- simplify_eq H0; intro.
- exists (Locmap.set (R (loc_result (funsig tf))) res ls); split.
- subst tf. eapply exec_funct_external; eauto.
- apply Locmap.gss.
+ (* Icond, true *)
+ assert (COND: eval_condition cond (map ls (map assign args)) tm = Some true).
+ eapply eval_condition_lessdef; eauto.
+ eapply agree_eval_regs; eauto.
+ econstructor; split.
+ eapply exec_Lcond_true; eauto. TranslInstr.
+ MatchStates. eapply agree_reg_list_live. eauto.
+ (* Icond, false *)
+ assert (COND: eval_condition cond (map ls (map assign args)) tm = Some false).
+ eapply eval_condition_lessdef; eauto.
+ eapply agree_eval_regs; eauto.
+ econstructor; split.
+ eapply exec_Lcond_false; eauto. TranslInstr.
+ MatchStates. eapply agree_reg_list_live. eauto.
+
+ (* Ireturn *)
+ econstructor; split.
+ eapply exec_Lreturn; eauto. TranslInstr; eauto.
+ econstructor; eauto.
+ rewrite return_regs_result.
+ inv WTI. destruct or; simpl in *.
+ rewrite Locmap.gss. eapply agree_eval_reg; eauto.
+ constructor.
+ apply free_lessdef; auto.
+ intros. apply return_regs_not_destroyed; auto.
+
+ (* internal function *)
+ generalize H6. simpl. unfold transf_function.
+ caseEq (type_function f); simpl; try congruence. intros env TYP.
+ assert (WTF: wt_function f env). apply type_function_correct; auto.
+ caseEq (analyze f); simpl; try congruence. intros live ANL.
+ caseEq (regalloc f live (live0 f live) env); simpl; try congruence.
+ intros alloc ALLOC EQ. inv EQ. simpl in *.
+ caseEq (Mem.alloc tm 0 (RTL.fn_stacksize f)). intros tm' stk' MEMALLOC.
+ exploit alloc_lessdef; eauto. intros [EQ LDM]. subst stk'.
+ econstructor; split.
+ eapply exec_function_internal; simpl; eauto.
+ simpl. econstructor; eauto.
+ apply agree_init_regs. intros; eapply regalloc_correct_3; eauto.
+ inv WTF.
+ exploit (parmov_spec (call_regs ls)
+ (loc_parameters (RTL.fn_sig f))
+ (map alloc (RTL.fn_params f))).
+ eapply regalloc_norepet_norepet; eauto.
+ eapply regalloc_correct_2; eauto.
+ rewrite loc_parameters_length. symmetry.
+ transitivity (length (map env (RTL.fn_params f))).
+ repeat rewrite list_length_map. auto.
+ rewrite wt_params; auto.
+ intros [PM1 PM2].
+ change Regset.elt with reg in PM1. rewrite PM1.
+ replace (map (call_regs ls) (loc_parameters (RTL.fn_sig f)))
+ with (map ls (loc_arguments (RTL.fn_sig f))).
+ auto.
+ symmetry. unfold loc_parameters. rewrite list_map_compose.
+ apply list_map_exten. intros. symmetry. eapply call_regs_param_of_arg; eauto.
+
+ (* external function *)
+ injection H6; intro EQ; inv EQ.
+ exploit event_match_lessdef; eauto. intros [tres [A B]].
+ econstructor; split.
+ eapply exec_function_external; eauto.
+ eapply match_states_return; eauto.
+ rewrite Locmap.gss. auto.
+ intros. rewrite <- H10; auto. apply Locmap.gso.
+ apply Loc.diff_sym. eapply Loc.in_notin_diff; eauto.
+ apply loc_result_caller_save.
+
+ (* return *)
+ inv H3.
+ econstructor; split.
+ eapply exec_return; eauto.
+ econstructor; eauto.
Qed.
-(** The correctness of the code transformation is obtained by
- structural induction (and case analysis on the last rule used)
- on the RTL evaluation derivation.
- This is a 3-way mutual induction, using [exec_instr_prop],
- [exec_instrs_prop] and [exec_function_prop] as the induction
- hypotheses, and the lemmas above as cases for the induction. *)
-
-Theorem transl_function_correctness:
- forall f args m t res m',
- RTL.exec_function ge f args m t res m' ->
- exec_function_prop f args m t res m'.
-Proof
- (exec_function_ind_3 ge
- exec_instr_prop
- exec_instrs_prop
- exec_function_prop
-
- transl_Inop_correct
- transl_Iop_correct
- transl_Iload_correct
- transl_Istore_correct
- transl_Icall_correct
- transl_Ialloc_correct
- transl_Icond_true_correct
- transl_Icond_false_correct
-
- transl_refl_correct
- transl_one_correct
- transl_trans_correct
-
- transl_function_correct
- transl_external_function_correct).
-
(** The semantic equivalence between the original and transformed programs
follows easily. *)
-Theorem transl_program_correct:
- forall (t: trace) (r: val),
- RTL.exec_program prog t r -> LTL.exec_program tprog t r.
+Lemma transf_initial_states:
+ forall st1, RTL.initial_state prog st1 ->
+ exists st2, LTL.initial_state tprog st2 /\ match_states st1 st2.
Proof.
- intros t r [b [f [m [FIND1 [FIND2 [SIG EXEC]]]]]].
- generalize (function_ptr_translated _ _ FIND2).
- intros [tf [TFIND TRF]].
+ intros. inversion H.
+ exploit function_ptr_translated; eauto. intros [tf [FIND TR]].
assert (SIG2: funsig tf = mksignature nil (Some Tint)).
- rewrite <- SIG. apply sig_function_translated; auto.
- assert (VPARAMS: map (Locmap.init Vundef) (loc_arguments (funsig tf)) = nil).
- rewrite SIG2. reflexivity.
- generalize (transl_function_correctness _ _ _ _ _ _ EXEC
- (Locmap.init Vundef) tf TRF VPARAMS).
- intros [ls' [TEXEC RES]].
- red. exists b; exists tf; exists ls'; exists m.
- split. rewrite symbols_preserved.
- rewrite (transform_partial_program_main _ _ TRANSF).
- assumption.
- split. assumption.
- split. assumption.
- split. replace (Genv.init_mem tprog) with (Genv.init_mem prog).
- assumption. symmetry.
- exact (Genv.init_mem_transf_partial _ _ TRANSF).
- assumption.
+ rewrite <- H2. apply sig_function_translated; auto.
+ assert (VPARAMS: Val.lessdef_list nil (map (Locmap.init Vundef) (loc_arguments (funsig tf)))).
+ rewrite SIG2. simpl. constructor.
+ assert (GENV: (Genv.init_mem tprog) = (Genv.init_mem prog)).
+ exact (Genv.init_mem_transf_partial _ _ TRANSF).
+ assert (MMD: Mem.lessdef (Genv.init_mem prog) (Genv.init_mem tprog)).
+ rewrite GENV. apply Mem.lessdef_refl.
+ exists (LTL.Callstate nil tf (Locmap.init Vundef) (Genv.init_mem tprog)); split.
+ econstructor; eauto.
+ rewrite symbols_preserved.
+ rewrite (transform_partial_program_main _ _ TRANSF). auto.
+ constructor; auto. rewrite H2; constructor.
+Qed.
+
+Lemma transf_final_states:
+ forall st1 st2 r,
+ match_states st1 st2 -> RTL.final_state st1 r -> LTL.final_state st2 r.
+Proof.
+ intros. inv H0. inv H. inv H3. econstructor.
+ inv H4. auto.
+Qed.
+
+Theorem transf_program_correct:
+ forall (beh: program_behavior),
+ RTL.exec_program prog beh -> LTL.exec_program tprog beh.
+Proof.
+ unfold RTL.exec_program, LTL.exec_program; intros.
+ eapply simulation_step_preservation; eauto.
+ eexact transf_initial_states.
+ eexact transf_final_states.
+ exact transl_step_correct.
Qed.
End PRESERVATION.
diff --git a/backend/Alloctyping.v b/backend/Alloctyping.v
index 4c4c4f7..c0abf0d 100644
--- a/backend/Alloctyping.v
+++ b/backend/Alloctyping.v
@@ -2,6 +2,7 @@
Require Import Coqlib.
Require Import Maps.
+Require Import Errors.
Require Import AST.
Require Import Op.
Require Import Registers.
@@ -15,7 +16,6 @@ Require Import Allocproof.
Require Import RTLtyping.
Require Import LTLtyping.
Require Import Conventions.
-Require Import Parallelmove.
(** This file proves that register allocation (the translation from
RTL to LTL defined in file [Allocation]) preserves typing:
@@ -30,9 +30,10 @@ Variable live: PMap.t Regset.t.
Variable alloc: reg -> loc.
Variable tf: LTL.function.
-Hypothesis TYPE_RTL: type_function f = Some env.
+Hypothesis TYPE_RTL: type_function f = OK env.
+Hypothesis LIVE: analyze f = Some live.
Hypothesis ALLOC: regalloc f live (live0 f live) env = Some alloc.
-Hypothesis TRANSL: transf_function f = Some tf.
+Hypothesis TRANSL: transf_function f = OK tf.
Lemma wt_rtl_function: RTLtyping.wt_function f env.
Proof.
@@ -51,473 +52,90 @@ Proof.
intros. symmetry. apply alloc_type.
Qed.
-(** [loc_read_ok l] states whether location [l] is well-formed in an
- argument context (for reading). *)
-
-Definition loc_read_ok (l: loc) : Prop :=
- match l with R r => True | S s => slot_bounded tf s end.
-
-(** [loc_write_ok l] states whether location [l] is well-formed in a
- result context (for writing). *)
-
-Definition loc_write_ok (l: loc) : Prop :=
- match l with
- | R r => True
- | S (Incoming _ _) => False
- | S s => slot_bounded tf s end.
-
-Definition locs_read_ok (ll: list loc) : Prop :=
- forall l, In l ll -> loc_read_ok l.
-
-Definition locs_write_ok (ll: list loc) : Prop :=
- forall l, In l ll -> loc_write_ok l.
-
-Remark loc_write_ok_read_ok:
- forall l, loc_write_ok l -> loc_read_ok l.
-Proof.
- destruct l; simpl. auto.
- destruct s; tauto.
-Qed.
-Hint Resolve loc_write_ok_read_ok: allocty.
-
-Remark locs_write_ok_read_ok:
- forall ll, locs_write_ok ll -> locs_read_ok ll.
-Proof.
- unfold locs_write_ok, locs_read_ok. auto with allocty.
-Qed.
-Hint Resolve locs_write_ok_read_ok: allocty.
-
-Lemma alloc_write_ok:
- forall r, loc_write_ok (alloc r).
+Lemma alloc_acceptable:
+ forall r, loc_acceptable (alloc r).
Proof.
- intros. generalize (regalloc_acceptable _ _ _ _ _ r ALLOC).
- destruct (alloc r); simpl. auto.
- destruct s; try contradiction. simpl. omega.
+ intros. eapply regalloc_acceptable; eauto.
Qed.
-Hint Resolve alloc_write_ok: allocty.
-Lemma allocs_write_ok:
- forall rl, locs_write_ok (List.map alloc rl).
+Lemma allocs_acceptable:
+ forall rl, locs_acceptable (List.map alloc rl).
Proof.
- intros; red; intros.
- generalize (list_in_map_inv _ _ _ H). intros [r [EQ IN]].
- subst l. auto with allocty.
+ intros. eapply regsalloc_acceptable; eauto.
Qed.
-Hint Resolve allocs_write_ok: allocty.
-
-(** * Typing LTL constructors *)
-
-(** We show that the LTL constructor functions defined in [Allocation]
- generate well-typed LTL basic blocks, given sufficient typing
- and well-formedness hypotheses over the locations involved. *)
-Lemma wt_add_reload:
- forall src dst k,
- loc_read_ok src ->
- Loc.type src = mreg_type dst ->
- wt_block tf k ->
- wt_block tf (add_reload src dst k).
+Remark transf_unroll:
+ tf = transf_fun f live alloc.
Proof.
- intros. unfold add_reload. destruct src.
- case (mreg_eq m dst); intro. auto. apply wt_Bopmove. exact H0. auto.
- apply wt_Bgetstack. exact H0. exact H. auto.
+ generalize TRANSL. unfold transf_function.
+ rewrite TYPE_RTL. rewrite LIVE. rewrite ALLOC. congruence.
Qed.
-Lemma wt_add_spill:
- forall src dst k,
- loc_write_ok dst ->
- mreg_type src = Loc.type dst ->
- wt_block tf k ->
- wt_block tf (add_spill src dst k).
+Lemma valid_successor_transf:
+ forall s,
+ RTLtyping.valid_successor f s ->
+ LTLtyping.valid_successor tf s.
Proof.
- intros. unfold add_spill. destruct dst.
- case (mreg_eq src m); intro. auto.
- apply wt_Bopmove. exact H0. auto.
- apply wt_Bsetstack. generalize H. simpl. destruct s; auto.
- symmetry. exact H0. generalize H. simpl. destruct s; auto. contradiction.
- auto.
-Qed.
+ unfold RTLtyping.valid_successor, LTLtyping.valid_successor.
+ intros s [i AT].
+ rewrite transf_unroll; simpl. rewrite PTree.gmap.
+ rewrite AT. exists (transf_instr f live alloc s i). auto.
+Qed.
-Lemma wt_add_reloads:
- forall srcs dsts k,
- locs_read_ok srcs ->
- List.map Loc.type srcs = List.map mreg_type dsts ->
- wt_block tf k ->
- wt_block tf (add_reloads srcs dsts k).
-Proof.
- induction srcs; intros.
- destruct dsts. simpl; auto. simpl in H0; discriminate.
- destruct dsts; simpl in H0. discriminate. simpl.
- apply wt_add_reload. apply H; apply in_eq. congruence.
- apply IHsrcs. red; intros; apply H; apply in_cons; auto.
- congruence. auto.
-Qed.
-
-Lemma wt_reg_for:
- forall l, mreg_type (reg_for l) = Loc.type l.
-Proof.
- intros. destruct l; simpl. auto.
- case (slot_type s); reflexivity.
-Qed.
-Hint Resolve wt_reg_for: allocty.
-
-Lemma wt_regs_for_rec:
- forall locs itmps ftmps,
- (List.length locs <= List.length itmps)%nat ->
- (List.length locs <= List.length ftmps)%nat ->
- (forall r, In r itmps -> mreg_type r = Tint) ->
- (forall r, In r ftmps -> mreg_type r = Tfloat) ->
- List.map mreg_type (regs_for_rec locs itmps ftmps) = List.map Loc.type locs.
-Proof.
- induction locs; intros.
- simpl. auto.
- destruct itmps; simpl in H. omegaContradiction.
- destruct ftmps; simpl in H0. omegaContradiction.
- simpl. apply (f_equal2 (@cons typ)).
- destruct a. reflexivity. simpl. case (slot_type s).
- apply H1; apply in_eq. apply H2; apply in_eq.
- apply IHlocs. omega. omega.
- intros; apply H1; apply in_cons; auto.
- intros; apply H2; apply in_cons; auto.
-Qed.
-
-Lemma wt_regs_for:
- forall locs,
- (List.length locs <= 3)%nat ->
- List.map mreg_type (regs_for locs) = List.map Loc.type locs.
-Proof.
- intros. unfold regs_for. apply wt_regs_for_rec.
- simpl. auto. simpl. auto.
- simpl; intros; intuition; subst r; reflexivity.
- simpl; intros; intuition; subst r; reflexivity.
-Qed.
-Hint Resolve wt_regs_for: allocty.
-
-Lemma wt_add_move:
- forall src dst b,
- loc_read_ok src -> loc_write_ok dst ->
- Loc.type src = Loc.type dst ->
- wt_block tf b ->
- wt_block tf (add_move src dst b).
-Proof.
- intros. unfold add_move.
- case (Loc.eq src dst); intro.
- auto.
- destruct src. apply wt_add_spill; auto.
- destruct dst. apply wt_add_reload; auto.
- set (tmp := match slot_type s with Tint => IT1 | Tfloat => FT1 end).
- apply wt_add_reload. auto.
- simpl. unfold tmp. case (slot_type s); reflexivity.
- apply wt_add_spill. auto.
- simpl. simpl in H1. rewrite <- H1. unfold tmp. case (slot_type s); reflexivity.
- auto.
-Qed.
-
-Lemma wt_add_moves:
- forall b moves,
- (forall s d, In (s, d) moves ->
- loc_read_ok s /\ loc_write_ok d /\ Loc.type s = Loc.type d) ->
- wt_block tf b ->
- wt_block tf
- (List.fold_right (fun p k => add_move (fst p) (snd p) k) b moves).
-Proof.
- induction moves; simpl; intros.
- auto.
- destruct a as [s d]. simpl.
- elim (H s d). intros A [B C]. apply wt_add_move; auto. auto.
-Qed.
-
-Theorem wt_parallel_move:
- forall srcs dsts b,
- List.map Loc.type srcs = List.map Loc.type dsts ->
- locs_read_ok srcs ->
- locs_write_ok dsts -> wt_block tf b -> wt_block tf (parallel_move srcs dsts b).
-Proof.
- intros. unfold parallel_move. apply wt_add_moves; auto.
- intros.
- elim (parmove_prop_2 _ _ _ _ H3); intros A B.
- split. destruct A as [C|[C|C]].
- apply H0; auto. subst s; exact I. subst s; exact I.
- split. destruct B as [C|[C|C]].
- apply H1; auto. subst d; exact I. subst d; exact I.
- eapply parmove_prop_3; eauto.
-Qed.
-
-Lemma wt_add_op_move:
- forall src res s,
- Loc.type src = Loc.type res ->
- loc_read_ok src -> loc_write_ok res ->
- wt_block tf (add_op Omove (src :: nil) res s).
-Proof.
- intros. unfold add_op. simpl.
- apply wt_add_move. auto. auto. auto. constructor.
-Qed.
-
-Lemma wt_add_op_undef:
- forall res s,
- loc_write_ok res ->
- wt_block tf (add_op Oundef nil res s).
-Proof.
- intros. unfold add_op. simpl.
- apply wt_Bopundef. apply wt_add_spill. auto. auto with allocty.
- constructor.
-Qed.
-
-Lemma wt_add_op_others:
- forall op args res s,
- op <> Omove -> op <> Oundef ->
- (List.map Loc.type args, Loc.type res) = type_of_operation op ->
- locs_read_ok args ->
- loc_write_ok res ->
- wt_block tf (add_op op args res s).
-Proof.
- intros. unfold add_op.
- caseEq (is_move_operation op args). intros.
- generalize (is_move_operation_correct op args H4). tauto.
- intro. assert ((List.length args <= 3)%nat).
- replace (length args) with (length (fst (type_of_operation op))).
- apply Allocproof.length_type_of_operation.
- rewrite <- H1. simpl. apply list_length_map.
- generalize (wt_regs_for args H5); intro.
- generalize (wt_reg_for res); intro.
- apply wt_add_reloads. auto. auto.
- apply wt_Bop. auto. auto. congruence.
- apply wt_add_spill. auto. auto. constructor.
-Qed.
-
-Lemma wt_add_load:
- forall chunk addr args dst s,
- List.map Loc.type args = type_of_addressing addr ->
- Loc.type dst = type_of_chunk chunk ->
- locs_read_ok args ->
- loc_write_ok dst ->
- wt_block tf (add_load chunk addr args dst s).
-Proof.
- intros. unfold add_load.
- assert ((List.length args <= 2)%nat).
- replace (length args) with (length (type_of_addressing addr)).
- apply Allocproof.length_type_of_addressing.
- rewrite <- H. apply list_length_map.
- assert ((List.length args <= 3)%nat). omega.
- generalize (wt_regs_for args H4); intro.
- generalize (wt_reg_for dst); intro.
- apply wt_add_reloads. auto. auto.
- apply wt_Bload. congruence. congruence.
- apply wt_add_spill. auto. auto. constructor.
-Qed.
-
-Lemma wt_add_store:
- forall chunk addr args src s,
- List.map Loc.type args = type_of_addressing addr ->
- Loc.type src = type_of_chunk chunk ->
- locs_read_ok args ->
- loc_read_ok src ->
- wt_block tf (add_store chunk addr args src s).
-Proof.
- intros. unfold add_store.
- assert ((List.length args <= 2)%nat).
- replace (length args) with (length (type_of_addressing addr)).
- apply Allocproof.length_type_of_addressing.
- rewrite <- H. apply list_length_map.
- assert ((List.length (src :: args) <= 3)%nat). simpl. omega.
- generalize (wt_regs_for (src :: args) H4); intro.
- caseEq (regs_for (src :: args)).
- intro. constructor.
- intros rsrc rargs EQ. rewrite EQ in H5. simpl in H5.
- apply wt_add_reloads.
- red; intros. elim H6; intro. subst l; auto. auto.
- simpl. congruence.
- apply wt_Bstore. congruence. congruence. constructor.
-Qed.
-
-Lemma wt_add_call:
- forall sig los args res s,
- match los with inl l => Loc.type l = Tint | inr s => True end ->
- List.map Loc.type args = sig.(sig_args) ->
- Loc.type res = match sig.(sig_res) with None => Tint | Some ty => ty end ->
- locs_read_ok args ->
- match los with inl l => loc_read_ok l | inr s => True end ->
- loc_write_ok res ->
- wt_block tf (add_call sig los args res s).
-Proof.
- intros.
- assert (locs_write_ok (loc_arguments sig)).
- red; intros. generalize (loc_arguments_acceptable sig l H5).
- destruct l; simpl. auto.
- destruct s0; try contradiction. simpl. omega.
- unfold add_call. destruct los.
- apply wt_add_reload. auto. simpl; congruence.
- apply wt_parallel_move. rewrite loc_arguments_type. auto.
- auto. auto.
- apply wt_Bcall. reflexivity.
- apply wt_add_spill. auto.
- rewrite loc_result_type. auto. constructor.
- apply wt_parallel_move. rewrite loc_arguments_type. auto.
- auto. auto.
- apply wt_Bcall. auto.
- apply wt_add_spill. auto.
- rewrite loc_result_type. auto. constructor.
-Qed.
-
-Lemma wt_add_alloc:
- forall arg res s,
- Loc.type arg = Tint -> Loc.type res = Tint ->
- loc_read_ok arg -> loc_write_ok res ->
- wt_block tf (add_alloc arg res s).
-Proof.
- intros.
- unfold add_alloc. apply wt_add_reload. auto. rewrite H; reflexivity.
- apply wt_Balloc. apply wt_add_spill. auto. rewrite H0; reflexivity.
- apply wt_Bgoto.
-Qed.
-
-Lemma wt_add_cond:
- forall cond args ifso ifnot,
- List.map Loc.type args = type_of_condition cond ->
- locs_read_ok args ->
- wt_block tf (add_cond cond args ifso ifnot).
-Proof.
- intros.
- assert ((List.length args) <= 3)%nat.
- replace (length args) with (length (type_of_condition cond)).
- apply Allocproof.length_type_of_condition.
- rewrite <- H. apply list_length_map.
- generalize (wt_regs_for args H1). intro.
- unfold add_cond. apply wt_add_reloads.
- auto. auto.
- apply wt_Bcond. congruence.
-Qed.
-
-Lemma wt_add_return:
- forall sig optarg,
- option_map Loc.type optarg = sig.(sig_res) ->
- match optarg with None => True | Some arg => loc_read_ok arg end ->
- wt_block tf (add_return sig optarg).
-Proof.
- intros. unfold add_return. destruct optarg.
- apply wt_add_reload. auto. rewrite loc_result_type.
- simpl in H. destruct (sig_res sig). congruence. discriminate.
- constructor.
- apply wt_Bopundef. constructor.
-Qed.
-
-Lemma wt_add_undefs:
- forall ll b,
- wt_block tf b -> wt_block tf (add_undefs ll b).
-Proof.
- induction ll; intros.
- simpl. auto.
- simpl. destruct a. apply wt_Bopundef. auto. auto.
-Qed.
-
-Lemma wt_add_entry:
- forall params undefs s,
- List.map Loc.type params = sig_args (RTL.fn_sig f) ->
- locs_write_ok params ->
- wt_block tf (add_entry (RTL.fn_sig f) params undefs s).
-Proof.
- set (sig := RTL.fn_sig f).
- assert (sig = tf.(fn_sig)).
- unfold sig.
- assert (transf_fundef (Internal f) = Some (Internal tf)).
- unfold transf_fundef, transf_partial_fundef. rewrite TRANSL; auto.
- generalize (Allocproof.sig_function_translated _ _ H). simpl; auto.
- assert (locs_read_ok (loc_parameters sig)).
- red; unfold loc_parameters. intros.
- generalize (list_in_map_inv _ _ _ H0). intros [l1 [EQ IN]].
- subst l. generalize (loc_arguments_acceptable _ _ IN).
- destruct l1. simpl. auto.
- destruct s; try contradiction.
- simpl; intros. split. omega. rewrite <- H.
- apply loc_arguments_bounded. auto.
- intros. unfold add_entry.
- apply wt_parallel_move. rewrite loc_parameters_type. auto.
- auto. auto.
- apply wt_add_undefs. constructor.
-Qed.
+Hint Resolve alloc_acceptable allocs_acceptable: allocty.
+Hint Rewrite alloc_type alloc_types: allocty.
+Hint Resolve valid_successor_transf: allocty.
(** * Type preservation during translation from RTL to LTL *)
+Ltac WT :=
+ constructor; auto with allocty; autorewrite with allocty; auto.
+
Lemma wt_transf_instr:
forall pc instr,
- RTLtyping.wt_instr env f.(RTL.fn_sig) instr ->
- wt_block tf (transf_instr f live alloc pc instr).
+ RTLtyping.wt_instr env f instr ->
+ wt_instr tf (transf_instr f live alloc pc instr).
Proof.
- intros. inversion H; simpl.
+ intros. inv H; simpl.
(* nop *)
- constructor.
+ WT.
(* move *)
- case (Regset.mem r live!!pc).
- apply wt_add_op_move; auto with allocty.
- repeat rewrite alloc_type. auto. constructor.
- (* undef *)
- case (Regset.mem r live!!pc).
- apply wt_add_op_undef; auto with allocty.
- constructor.
+ destruct (Regset.mem r live!!pc).
+ destruct (is_redundant_move Omove (r1 :: nil) r alloc); WT.
+ WT.
(* other ops *)
- case (Regset.mem res live!!pc).
- apply wt_add_op_others; auto with allocty.
- rewrite alloc_types. rewrite alloc_type. auto.
- constructor.
+ destruct (Regset.mem res live!!pc).
+ destruct (is_redundant_move op args res alloc); WT.
+ WT.
(* load *)
- case (Regset.mem dst live!!pc).
- apply wt_add_load; auto with allocty.
- rewrite alloc_types. auto. rewrite alloc_type. auto.
- constructor.
+ destruct (Regset.mem dst live!!pc); WT.
(* store *)
- apply wt_add_store; auto with allocty.
- rewrite alloc_types. auto. rewrite alloc_type. auto.
+ WT.
(* call *)
- apply wt_add_call.
- destruct ros; simpl. rewrite alloc_type; auto. auto.
- rewrite alloc_types; auto.
- rewrite alloc_type. auto.
- auto with allocty.
+ WT.
+ destruct ros; simpl. autorewrite with allocty; auto. auto.
+ destruct ros; simpl; auto with allocty.
+ (* tailcall *)
+ WT.
+ destruct ros; simpl. autorewrite with allocty; auto. auto.
destruct ros; simpl; auto with allocty.
- auto with allocty.
+ rewrite transf_unroll; auto.
(* alloc *)
- apply wt_add_alloc; auto with allocty.
- rewrite alloc_type; auto. rewrite alloc_type; auto.
+ WT.
(* cond *)
- apply wt_add_cond. rewrite alloc_types; auto. auto with allocty.
+ WT.
(* return *)
- apply wt_add_return.
- destruct optres; simpl. rewrite alloc_type. exact H0. exact H0.
+ WT.
+ rewrite transf_unroll; simpl.
+ destruct optres; simpl. autorewrite with allocty. auto. auto.
destruct optres; simpl; auto with allocty.
Qed.
-Lemma wt_transf_instrs:
- let c := PTree.map (transf_instr f live alloc) (RTL.fn_code f) in
- forall pc b, c!pc = Some b -> wt_block tf b.
-Proof.
- intros until b.
- unfold c. rewrite PTree.gmap. caseEq (RTL.fn_code f)!pc.
- intros instr EQ. simpl. intros. injection H; intro; subst b.
- apply wt_transf_instr. eapply RTLtyping.wt_instrs; eauto.
- apply wt_rtl_function.
- simpl; intros; discriminate.
-Qed.
-
-Lemma wt_transf_entrypoint:
- let c := transf_entrypoint f live alloc
- (PTree.map (transf_instr f live alloc) (RTL.fn_code f)) in
- (forall pc b, c!pc = Some b -> wt_block tf b).
-Proof.
- simpl. unfold transf_entrypoint.
- intros pc b. rewrite PTree.gsspec.
- case (peq pc (fn_nextpc f)); intros.
- injection H; intro; subst b.
- apply wt_add_entry.
- rewrite alloc_types. eapply RTLtyping.wt_params. apply wt_rtl_function.
- auto with allocty.
- apply wt_transf_instrs with pc; auto.
-Qed.
-
End TYPING_FUNCTION.
Lemma wt_transf_function:
forall f tf,
- transf_function f = Some tf -> wt_function tf.
+ transf_function f = OK tf -> wt_function tf.
Proof.
intros. generalize H; unfold transf_function.
caseEq (type_function f). intros env TYP.
@@ -527,19 +145,27 @@ Proof.
with (live0 f live).
caseEq (regalloc f live (live0 f live) env).
intros alloc ALLOC.
- intro EQ; injection EQ; intro; subst tf.
- red. simpl. intros. eapply wt_transf_entrypoint; eauto.
- intros; discriminate.
- intros; discriminate.
- intros; discriminate.
-Qed.
+ intro EQ; injection EQ; intro.
+ assert (RTLtyping.wt_function f env). apply type_function_correct; auto.
+ inversion H1.
+ constructor; rewrite <- H0; simpl.
+ rewrite (alloc_types _ _ _ _ ALLOC). auto.
+ eapply regsalloc_acceptable; eauto.
+ eapply regalloc_norepet_norepet; eauto.
+ eapply regalloc_correct_2; eauto.
+ intros until instr. rewrite PTree.gmap.
+ caseEq (RTL.fn_code f)!pc; simpl; intros.
+ inversion H3. eapply wt_transf_instr; eauto. congruence. discriminate.
+ eapply valid_successor_transf; eauto. congruence.
+ congruence. congruence. congruence.
+Qed.
Lemma wt_transf_fundef:
forall f tf,
- transf_fundef f = Some tf -> wt_fundef tf.
+ transf_fundef f = OK tf -> wt_fundef tf.
Proof.
intros until tf; destruct f; simpl.
- caseEq (transf_function f). intros g TF EQ. inversion EQ.
+ caseEq (transf_function f); simpl. intros g TF EQ. inversion EQ.
constructor. eapply wt_transf_function; eauto.
congruence.
intros. inversion H. constructor.
@@ -547,7 +173,7 @@ Qed.
Lemma program_typing_preserved:
forall (p: RTL.program) (tp: LTL.program),
- transf_program p = Some tp ->
+ transf_program p = OK tp ->
LTLtyping.wt_program tp.
Proof.
intros; red; intros.
diff --git a/backend/Bounds.v b/backend/Bounds.v
new file mode 100644
index 0000000..a0f09ce
--- /dev/null
+++ b/backend/Bounds.v
@@ -0,0 +1,357 @@
+(** Computation of resource bounds forr Linear code. *)
+
+Require Import Coqlib.
+Require Import Maps.
+Require Import AST.
+Require Import Op.
+Require Import Locations.
+Require Import Linear.
+Require Import Lineartyping.
+Require Import Conventions.
+
+(** * Resource bounds for a function *)
+
+(** The [bounds] record capture how many local and outgoing stack slots
+ and callee-save registers are used by a function. *)
+
+(** We demand that all bounds are positive or null,
+ and moreover [bound_outgoing] is greater or equal to 6.
+ These properties are used later to reason about the layout of
+ the activation record. *)
+
+Record bounds : Set := mkbounds {
+ bound_int_local: Z;
+ bound_float_local: Z;
+ bound_int_callee_save: Z;
+ bound_float_callee_save: Z;
+ bound_outgoing: Z;
+ bound_int_local_pos: bound_int_local >= 0;
+ bound_float_local_pos: bound_float_local >= 0;
+ bound_int_callee_save_pos: bound_int_callee_save >= 0;
+ bound_float_callee_save_pos: bound_float_callee_save >= 0;
+ bound_outgoing_pos: bound_outgoing >= 6
+}.
+
+(** The following predicates define the correctness of a set of bounds
+ for the code of a function. *)
+
+Section BELOW.
+
+Variable funct: function.
+Variable b: bounds.
+
+Definition mreg_within_bounds (r: mreg) :=
+ match mreg_type r with
+ | Tint => index_int_callee_save r < bound_int_callee_save b
+ | Tfloat => index_float_callee_save r < bound_float_callee_save b
+ end.
+
+Definition slot_within_bounds (s: slot) :=
+ match s with
+ | Local ofs Tint => 0 <= ofs < bound_int_local b
+ | Local ofs Tfloat => 0 <= ofs < bound_float_local b
+ | Outgoing ofs ty => 14 <= ofs /\ ofs + typesize ty <= bound_outgoing b
+ | Incoming ofs ty => 14 <= ofs /\ ofs + typesize ty <= size_arguments funct.(fn_sig)
+ end.
+
+Definition instr_within_bounds (i: instruction) :=
+ match i with
+ | Lgetstack s r => slot_within_bounds s /\ mreg_within_bounds r
+ | Lsetstack r s => slot_within_bounds s
+ | Lop op args res => mreg_within_bounds res
+ | Lload chunk addr args dst => mreg_within_bounds dst
+ | Lcall sig ros => size_arguments sig <= bound_outgoing b
+ | _ => True
+ end.
+
+End BELOW.
+
+Definition function_within_bounds (f: function) (b: bounds) : Prop :=
+ forall instr, In instr f.(fn_code) -> instr_within_bounds f b instr.
+
+(** * Inference of resource bounds for a function *)
+
+(** The resource bounds for a function are computed by a linear scan
+ of its instructions. *)
+
+Section BOUNDS.
+
+Variable f: function.
+
+(** In the proof of the [Stacking] pass, we only need to bound the
+ registers written by an instruction. Therefore, this function
+ returns these registers, ignoring registers used only as
+ arguments. *)
+
+Definition regs_of_instr (i: instruction) : list mreg :=
+ match i with
+ | Lgetstack s r => r :: nil
+ | Lsetstack r s => r :: nil
+ | Lop op args res => res :: nil
+ | Lload chunk addr args dst => dst :: nil
+ | Lstore chunk addr args src => nil
+ | Lcall sig ros => nil
+ | Ltailcall sig ros => nil
+ | Lalloc => nil
+ | Llabel lbl => nil
+ | Lgoto lbl => nil
+ | Lcond cond args lbl => nil
+ | Lreturn => nil
+ end.
+
+Definition slots_of_instr (i: instruction) : list slot :=
+ match i with
+ | Lgetstack s r => s :: nil
+ | Lsetstack r s => s :: nil
+ | _ => nil
+ end.
+
+Definition max_over_list (A: Set) (valu: A -> Z) (l: list A) : Z :=
+ List.fold_left (fun m l => Zmax m (valu l)) l 0.
+
+Definition max_over_instrs (valu: instruction -> Z) : Z :=
+ max_over_list instruction valu f.(fn_code).
+
+Definition max_over_regs_of_instr (valu: mreg -> Z) (i: instruction) : Z :=
+ max_over_list mreg valu (regs_of_instr i).
+
+Definition max_over_slots_of_instr (valu: slot -> Z) (i: instruction) : Z :=
+ max_over_list slot valu (slots_of_instr i).
+
+Definition max_over_regs_of_funct (valu: mreg -> Z) : Z :=
+ max_over_instrs (max_over_regs_of_instr valu).
+
+Definition max_over_slots_of_funct (valu: slot -> Z) : Z :=
+ max_over_instrs (max_over_slots_of_instr valu).
+
+Definition int_callee_save (r: mreg) := 1 + index_int_callee_save r.
+
+Definition float_callee_save (r: mreg) := 1 + index_float_callee_save r.
+
+Definition int_local (s: slot) :=
+ match s with Local ofs Tint => 1 + ofs | _ => 0 end.
+
+Definition float_local (s: slot) :=
+ match s with Local ofs Tfloat => 1 + ofs | _ => 0 end.
+
+Definition outgoing_slot (s: slot) :=
+ match s with Outgoing ofs ty => ofs + typesize ty | _ => 0 end.
+
+Definition outgoing_space (i: instruction) :=
+ match i with Lcall sig _ => size_arguments sig | _ => 0 end.
+
+Lemma max_over_list_pos:
+ forall (A: Set) (valu: A -> Z) (l: list A),
+ max_over_list A valu l >= 0.
+Proof.
+ intros until valu. unfold max_over_list.
+ assert (forall l z, fold_left (fun x y => Zmax x (valu y)) l z >= z).
+ induction l; simpl; intros.
+ omega. apply Zge_trans with (Zmax z (valu a)).
+ auto. apply Zle_ge. apply Zmax1. auto.
+Qed.
+
+Lemma max_over_slots_of_funct_pos:
+ forall (valu: slot -> Z), max_over_slots_of_funct valu >= 0.
+Proof.
+ intros. unfold max_over_slots_of_funct.
+ unfold max_over_instrs. apply max_over_list_pos.
+Qed.
+
+Lemma max_over_regs_of_funct_pos:
+ forall (valu: mreg -> Z), max_over_regs_of_funct valu >= 0.
+Proof.
+ intros. unfold max_over_regs_of_funct.
+ unfold max_over_instrs. apply max_over_list_pos.
+Qed.
+
+Remark Zmax_6: forall x, Zmax 6 x >= 6.
+Proof.
+ intros. apply Zle_ge. apply Zmax_bound_l. omega.
+Qed.
+
+Definition function_bounds :=
+ mkbounds
+ (max_over_slots_of_funct int_local)
+ (max_over_slots_of_funct float_local)
+ (max_over_regs_of_funct int_callee_save)
+ (max_over_regs_of_funct float_callee_save)
+ (Zmax 6
+ (Zmax (max_over_instrs outgoing_space)
+ (max_over_slots_of_funct outgoing_slot)))
+ (max_over_slots_of_funct_pos int_local)
+ (max_over_slots_of_funct_pos float_local)
+ (max_over_regs_of_funct_pos int_callee_save)
+ (max_over_regs_of_funct_pos float_callee_save)
+ (Zmax_6 _).
+
+(** We now show the correctness of the inferred bounds. *)
+
+Lemma max_over_list_bound:
+ forall (A: Set) (valu: A -> Z) (l: list A) (x: A),
+ In x l -> valu x <= max_over_list A valu l.
+Proof.
+ intros until x. unfold max_over_list.
+ assert (forall c z,
+ let f := fold_left (fun x y => Zmax x (valu y)) c z in
+ z <= f /\ (In x c -> valu x <= f)).
+ induction c; simpl; intros.
+ split. omega. tauto.
+ elim (IHc (Zmax z (valu a))); intros.
+ split. apply Zle_trans with (Zmax z (valu a)). apply Zmax1. auto.
+ intro H1; elim H1; intro.
+ subst a. apply Zle_trans with (Zmax z (valu x)).
+ apply Zmax2. auto. auto.
+ intro. elim (H l 0); intros. auto.
+Qed.
+
+Lemma max_over_instrs_bound:
+ forall (valu: instruction -> Z) i,
+ In i f.(fn_code) -> valu i <= max_over_instrs valu.
+Proof.
+ intros. unfold max_over_instrs. apply max_over_list_bound; auto.
+Qed.
+
+Lemma max_over_regs_of_funct_bound:
+ forall (valu: mreg -> Z) i r,
+ In i f.(fn_code) -> In r (regs_of_instr i) ->
+ valu r <= max_over_regs_of_funct valu.
+Proof.
+ intros. unfold max_over_regs_of_funct.
+ apply Zle_trans with (max_over_regs_of_instr valu i).
+ unfold max_over_regs_of_instr. apply max_over_list_bound. auto.
+ apply max_over_instrs_bound. auto.
+Qed.
+
+Lemma max_over_slots_of_funct_bound:
+ forall (valu: slot -> Z) i s,
+ In i f.(fn_code) -> In s (slots_of_instr i) ->
+ valu s <= max_over_slots_of_funct valu.
+Proof.
+ intros. unfold max_over_slots_of_funct.
+ apply Zle_trans with (max_over_slots_of_instr valu i).
+ unfold max_over_slots_of_instr. apply max_over_list_bound. auto.
+ apply max_over_instrs_bound. auto.
+Qed.
+
+Lemma int_callee_save_bound:
+ forall i r,
+ In i f.(fn_code) -> In r (regs_of_instr i) ->
+ index_int_callee_save r < bound_int_callee_save function_bounds.
+Proof.
+ intros. apply Zlt_le_trans with (int_callee_save r).
+ unfold int_callee_save. omega.
+ unfold function_bounds, bound_int_callee_save.
+ eapply max_over_regs_of_funct_bound; eauto.
+Qed.
+
+Lemma float_callee_save_bound:
+ forall i r,
+ In i f.(fn_code) -> In r (regs_of_instr i) ->
+ index_float_callee_save r < bound_float_callee_save function_bounds.
+Proof.
+ intros. apply Zlt_le_trans with (float_callee_save r).
+ unfold float_callee_save. omega.
+ unfold function_bounds, bound_float_callee_save.
+ eapply max_over_regs_of_funct_bound; eauto.
+Qed.
+
+Lemma int_local_slot_bound:
+ forall i ofs,
+ In i f.(fn_code) -> In (Local ofs Tint) (slots_of_instr i) ->
+ ofs < bound_int_local function_bounds.
+Proof.
+ intros. apply Zlt_le_trans with (int_local (Local ofs Tint)).
+ unfold int_local. omega.
+ unfold function_bounds, bound_int_local.
+ eapply max_over_slots_of_funct_bound; eauto.
+Qed.
+
+Lemma float_local_slot_bound:
+ forall i ofs,
+ In i f.(fn_code) -> In (Local ofs Tfloat) (slots_of_instr i) ->
+ ofs < bound_float_local function_bounds.
+Proof.
+ intros. apply Zlt_le_trans with (float_local (Local ofs Tfloat)).
+ unfold float_local. omega.
+ unfold function_bounds, bound_float_local.
+ eapply max_over_slots_of_funct_bound; eauto.
+Qed.
+
+Lemma outgoing_slot_bound:
+ forall i ofs ty,
+ In i f.(fn_code) -> In (Outgoing ofs ty) (slots_of_instr i) ->
+ ofs + typesize ty <= bound_outgoing function_bounds.
+Proof.
+ intros. change (ofs + typesize ty) with (outgoing_slot (Outgoing ofs ty)).
+ unfold function_bounds, bound_outgoing.
+ apply Zmax_bound_r. apply Zmax_bound_r.
+ eapply max_over_slots_of_funct_bound; eauto.
+Qed.
+
+Lemma size_arguments_bound:
+ forall sig ros,
+ In (Lcall sig ros) f.(fn_code) ->
+ size_arguments sig <= bound_outgoing function_bounds.
+Proof.
+ intros. change (size_arguments sig) with (outgoing_space (Lcall sig ros)).
+ unfold function_bounds, bound_outgoing.
+ apply Zmax_bound_r. apply Zmax_bound_l.
+ apply max_over_instrs_bound; auto.
+Qed.
+
+(** Consequently, all machine registers or stack slots mentioned by one
+ of the instructions of function [f] are within bounds. *)
+
+Lemma mreg_is_within_bounds:
+ forall i, In i f.(fn_code) ->
+ forall r, In r (regs_of_instr i) ->
+ mreg_within_bounds function_bounds r.
+Proof.
+ intros. unfold mreg_within_bounds.
+ case (mreg_type r).
+ eapply int_callee_save_bound; eauto.
+ eapply float_callee_save_bound; eauto.
+Qed.
+
+Lemma slot_is_within_bounds:
+ forall i, In i f.(fn_code) ->
+ forall s, In s (slots_of_instr i) -> Lineartyping.slot_valid f s ->
+ slot_within_bounds f function_bounds s.
+Proof.
+ intros. unfold slot_within_bounds.
+ destruct s.
+ destruct t.
+ split. exact H1. eapply int_local_slot_bound; eauto.
+ split. exact H1. eapply float_local_slot_bound; eauto.
+ exact H1.
+ split. exact H1. eapply outgoing_slot_bound; eauto.
+Qed.
+
+(** It follows that every instruction in the function is within bounds,
+ in the sense of the [instr_within_bounds] predicate. *)
+
+Lemma instr_is_within_bounds:
+ forall i,
+ In i f.(fn_code) ->
+ Lineartyping.wt_instr f i ->
+ instr_within_bounds f function_bounds i.
+Proof.
+ intros;
+ destruct i;
+ generalize (mreg_is_within_bounds _ H); generalize (slot_is_within_bounds _ H);
+ simpl; intros; auto.
+ inv H0. split; auto.
+ inv H0; auto.
+ eapply size_arguments_bound; eauto.
+Qed.
+
+Lemma function_is_within_bounds:
+ Lineartyping.wt_code f f.(fn_code) ->
+ function_within_bounds f function_bounds.
+Proof.
+ intros; red; intros. apply instr_is_within_bounds; auto.
+Qed.
+
+End BOUNDS.
+
diff --git a/backend/CSE.v b/backend/CSE.v
index 6801013..a7901d6 100644
--- a/backend/CSE.v
+++ b/backend/CSE.v
@@ -251,7 +251,7 @@ Definition equation_holds
(vres: valnum) (rh: rhs) : Prop :=
match rh with
| Op op vl =>
- eval_operation ge sp op (List.map valuation vl) =
+ eval_operation ge sp op (List.map valuation vl) m =
Some (valuation vres)
| Load chunk addr vl =>
exists a,
@@ -337,6 +337,8 @@ Definition transfer (f: function) (pc: node) (before: numbering) :=
kill_loads before
| Icall sig ros args res s =>
empty_numbering
+ | Itailcall sig ros args =>
+ empty_numbering
| Ialloc arg res s =>
add_unknown before res
| Icond cond args ifso ifnot =>
@@ -373,7 +375,6 @@ Definition is_trivial_op (op: operation) : bool :=
| Ointconst _ => true
| Oaddrsymbol _ _ => true
| Oaddrstack _ => true
- | Oundef => true
| _ => false
end.
@@ -426,7 +427,8 @@ Definition transf_function (f: function) : function :=
f.(fn_nextpc)
(transf_code_wf f approxs f.(fn_code_wf)).
-Definition transf_fundef := AST.transf_fundef transf_function.
+Definition transf_fundef (f: fundef) : fundef :=
+ AST.transf_fundef transf_function f.
Definition transf_program (p: program) : program :=
transform_program transf_fundef p.
diff --git a/backend/CSEproof.v b/backend/CSEproof.v
index 79657c5..d46a39f 100644
--- a/backend/CSEproof.v
+++ b/backend/CSEproof.v
@@ -9,6 +9,7 @@ Require Import Values.
Require Import Mem.
Require Import Events.
Require Import Globalenvs.
+Require Import Smallstep.
Require Import Op.
Require Import Registers.
Require Import RTL.
@@ -218,6 +219,7 @@ Proof.
apply wf_add_load; auto.
apply wf_kill_loads; auto.
apply wf_empty_numbering.
+ apply wf_empty_numbering.
apply wf_add_unknown; auto.
Qed.
@@ -387,7 +389,7 @@ Definition rhs_evals_to
(valu: valnum -> val) (rh: rhs) (v: val) : Prop :=
match rh with
| Op op vl =>
- eval_operation ge sp op (List.map valu vl) = Some v
+ eval_operation ge sp op (List.map valu vl) m = Some v
| Load chunk addr vl =>
exists a,
eval_addressing ge sp addr (List.map valu vl) = Some a /\
@@ -468,7 +470,7 @@ Lemma add_op_satisfiable:
forall n rs op args dst v,
wf_numbering n ->
numbering_satisfiable ge sp rs m n ->
- eval_operation ge sp op rs##args = Some v ->
+ eval_operation ge sp op rs##args m = Some v ->
numbering_satisfiable ge sp (rs#dst <- v) m (add_op n dst op args).
Proof.
intros. inversion H0.
@@ -545,7 +547,7 @@ Proof.
intros. destruct H0 as [valu [A B]].
exists valu; split; intros.
generalize (A _ _ H0). destruct rh; simpl.
- auto.
+ intro. eapply eval_operation_alloc; eauto.
intros [addr [C D]]. exists addr; split. auto.
destruct addr; simpl in *; try discriminate.
eapply Mem.load_alloc_other; eauto.
@@ -569,17 +571,21 @@ Proof.
Qed.
Lemma kill_load_satisfiable:
- forall n rs m',
+ forall n rs chunk addr v m',
+ Mem.storev chunk m addr v = Some m' ->
numbering_satisfiable ge sp rs m n ->
numbering_satisfiable ge sp rs m' (kill_loads n).
Proof.
- intros. inversion H. inversion H0.
+ intros. inversion H0. inversion H1.
generalize (kill_load_eqs_incl n.(num_eqs)). intro.
exists x. split; intros.
- generalize (H1 _ _ (H3 _ H4)).
- generalize (kill_load_eqs_ops _ _ _ H4).
- destruct rh; simpl. auto. tauto.
- apply H2. assumption.
+ generalize (H2 _ _ (H4 _ H5)).
+ generalize (kill_load_eqs_ops _ _ _ H5).
+ destruct rh; simpl.
+ intros. destruct addr; simpl in H; try discriminate.
+ eapply eval_operation_store; eauto.
+ tauto.
+ apply H3. assumption.
Qed.
(** Correctness of [reg_valnum]: if it returns a register [r],
@@ -633,7 +639,7 @@ Lemma find_op_correct:
wf_numbering n ->
numbering_satisfiable ge sp rs m n ->
find_op n op args = Some r ->
- eval_operation ge sp op rs##args = Some rs#r.
+ eval_operation ge sp op rs##args m = Some rs#r.
Proof.
intros until r. intros WF [valu NH].
unfold find_op. caseEq (valnum_regs n args). intros n' vl VR FIND.
@@ -664,29 +670,6 @@ Qed.
End SATISFIABILITY.
-(** The transfer function preserves satisfiability of numberings. *)
-
-Lemma transfer_correct:
- forall ge c sp pc rs m t pc' rs' m' f n,
- exec_instr ge c sp pc rs m t pc' rs' m' ->
- c = f.(fn_code) ->
- wf_numbering n ->
- numbering_satisfiable ge sp rs m n ->
- numbering_satisfiable ge sp rs' m' (transfer f pc n).
-Proof.
- induction 1; intros; subst c; unfold transfer; rewrite H; auto.
- (* Iop *)
- eapply add_op_satisfiable; eauto.
- (* Iload *)
- eapply add_load_satisfiable; eauto.
- (* Istore *)
- eapply kill_load_satisfiable; eauto.
- (* Icall *)
- apply empty_numbering_satisfiable.
- (* Ialloc *)
- apply add_unknown_satisfiable; auto. eapply alloc_satisfiable; eauto.
-Qed.
-
(** The numberings associated to each instruction by the static analysis
are inductively satisfiable, in the following sense: the numbering
at the function entry point is satisfiable, and for any RTL execution
@@ -694,43 +677,25 @@ Qed.
satisfiability at [pc']. *)
Theorem analysis_correct_1:
- forall ge c sp pc rs m t pc' rs' m' f,
- exec_instr ge c sp pc rs m t pc' rs' m' ->
- c = f.(fn_code) ->
- numbering_satisfiable ge sp rs m (analyze f)!!pc ->
- numbering_satisfiable ge sp rs' m' (analyze f)!!pc'.
+ forall ge sp rs m f pc pc',
+ In pc' (successors f pc) ->
+ numbering_satisfiable ge sp rs m (transfer f pc (analyze f)!!pc) ->
+ numbering_satisfiable ge sp rs m (analyze f)!!pc'.
Proof.
- intros until f. intros EXEC CODE.
+ intros until pc'.
generalize (wf_analyze f pc).
unfold analyze.
caseEq (Solver.fixpoint (successors f) (fn_nextpc f)
(transfer f) (fn_entrypoint f)).
- intros res FIXPOINT WF NS.
- assert (numbering_satisfiable ge sp rs' m' (transfer f pc res!!pc)).
- eapply transfer_correct; eauto.
+ intros res FIXPOINT WF SUCC NS.
assert (Numbering.ge res!!pc' (transfer f pc res!!pc)).
eapply Solver.fixpoint_solution; eauto.
elim (fn_code_wf f pc); intro. auto.
- rewrite <- CODE in H0.
- elim (exec_instr_present _ _ _ _ _ _ _ _ _ _ EXEC H0).
- rewrite CODE in EXEC. eapply successors_correct; eauto.
- apply H0. auto.
+ unfold successors in SUCC; rewrite H in SUCC; contradiction.
+ apply H. auto.
intros. rewrite PMap.gi. apply empty_numbering_satisfiable.
Qed.
-Theorem analysis_correct_N:
- forall ge c sp pc rs m t pc' rs' m' f,
- exec_instrs ge c sp pc rs m t pc' rs' m' ->
- c = f.(fn_code) ->
- numbering_satisfiable ge sp rs m (analyze f)!!pc ->
- numbering_satisfiable ge sp rs' m' (analyze f)!!pc'.
-Proof.
- induction 1; intros.
- assumption.
- eapply analysis_correct_1; eauto.
- eauto.
-Qed.
-
Theorem analysis_correct_entry:
forall ge sp rs m f,
numbering_satisfiable ge sp rs m (analyze f)!!(f.(fn_entrypoint)).
@@ -773,49 +738,67 @@ Lemma funct_ptr_translated:
Genv.find_funct_ptr tge b = Some (transf_fundef f).
Proof (@Genv.find_funct_ptr_transf _ _ _ transf_fundef prog).
-Lemma sig_translated:
- forall (f: RTL.fundef),
- funsig (transf_fundef f) = funsig f.
+Lemma sig_preserved:
+ forall f, funsig (transf_fundef f) = funsig f.
Proof.
- intros; case f; intros; reflexivity.
+ destruct f; reflexivity.
+Qed.
+
+Lemma find_function_translated:
+ forall ros rs f,
+ find_function ge ros rs = Some f ->
+ find_function tge ros rs = Some (transf_fundef f).
+Proof.
+ intros until f; destruct ros; simpl.
+ intro. apply functions_translated; auto.
+ rewrite symbols_preserved. destruct (Genv.find_symbol ge i); intro.
+ apply funct_ptr_translated; auto.
+ discriminate.
Qed.
(** The proof of semantic preservation is a simulation argument using
diagrams of the following form:
<<
- pc, rs, m ------------------------ pc, rs, m
- | |
- | |
- v v
- pc', rs', m' --------------------- pc', rs', m'
+ st1 --------------- st2
+ | |
+ t| |t
+ | |
+ v v
+ st1'--------------- st2'
>>
Left: RTL execution in the original program. Right: RTL execution in
- the optimized program. Precondition (top): the numbering at [pc]
- (returned by the static analysis) is satisfiable. Postcondition: none.
+ the optimized program. Precondition (top) and postcondition (bottom):
+ agreement between the states, including the fact that
+ the numbering at [pc] (returned by the static analysis) is satisfiable.
*)
-Definition exec_instr_prop
- (c: code) (sp: val)
- (pc: node) (rs: regset) (m: mem) (t: trace)
- (pc': node) (rs': regset) (m': mem) : Prop :=
- forall f
- (CF: c = f.(RTL.fn_code))
- (SAT: numbering_satisfiable ge sp rs m (analyze f)!!pc),
- exec_instr tge (transf_code (analyze f) c) sp pc rs m t pc' rs' m'.
-
-Definition exec_instrs_prop
- (c: code) (sp: val)
- (pc: node) (rs: regset) (m: mem) (t: trace)
- (pc': node) (rs': regset) (m': mem) : Prop :=
- forall f
- (CF: c = f.(RTL.fn_code))
- (SAT: numbering_satisfiable ge sp rs m (analyze f)!!pc),
- exec_instrs tge (transf_code (analyze f) c) sp pc rs m t pc' rs' m'.
-
-Definition exec_function_prop
- (f: RTL.fundef) (args: list val) (m: mem) (t: trace)
- (res: val) (m': mem) : Prop :=
- exec_function tge (transf_fundef f) args m t res m'.
+Inductive match_stackframes: stackframe -> stackframe -> Prop :=
+ match_stackframes_intro:
+ forall res c sp pc rs f,
+ c = f.(RTL.fn_code) ->
+ (forall v m, numbering_satisfiable ge sp (rs#res <- v) m (analyze f)!!pc) ->
+ match_stackframes
+ (Stackframe res c sp pc rs)
+ (Stackframe res (transf_code (analyze f) c) sp pc rs).
+
+Inductive match_states: state -> state -> Prop :=
+ | match_states_intro:
+ forall s c sp pc rs m s' f
+ (CF: c = f.(RTL.fn_code))
+ (SAT: numbering_satisfiable ge sp rs m (analyze f)!!pc)
+ (STACKS: list_forall2 match_stackframes s s'),
+ match_states (State s c sp pc rs m)
+ (State s' (transf_code (analyze f) c) sp pc rs m)
+ | match_states_call:
+ forall s f args m s',
+ list_forall2 match_stackframes s s' ->
+ match_states (Callstate s f args m)
+ (Callstate s' (transf_fundef f) args m)
+ | match_states_return:
+ forall s s' v m,
+ list_forall2 match_stackframes s s' ->
+ match_states (Returnstate s v m)
+ (Returnstate s' v m).
Ltac TransfInstr :=
match goal with
@@ -826,34 +809,49 @@ Ltac TransfInstr :=
unfold option_map; rewrite H1; reflexivity ]
end.
-(** The proof of simulation is by structural induction on the evaluation
- derivation for the source program. *)
+(** The proof of simulation is a case analysis over the transition
+ in the source code. *)
-Lemma transf_function_correct:
- forall f args m t res m',
- exec_function ge f args m t res m' ->
- exec_function_prop f args m t res m'.
+Lemma transf_step_correct:
+ forall s1 t s2, step ge s1 t s2 ->
+ forall s1' (MS: match_states s1 s1'),
+ exists s2', step tge s1' t s2' /\ match_states s2 s2'.
Proof.
- apply (exec_function_ind_3 ge
- exec_instr_prop exec_instrs_prop exec_function_prop);
- intros; red; intros; try TransfInstr.
+ induction 1; intros; inv MS; try (TransfInstr; intro C).
+
(* Inop *)
- intro; apply exec_Inop; auto.
+ exists (State s' (transf_code (analyze f) (fn_code f)) sp pc' rs m); split.
+ apply exec_Inop; auto.
+ econstructor; eauto.
+ apply analysis_correct_1 with pc.
+ unfold successors; rewrite H; auto with coqlib.
+ unfold transfer; rewrite H; auto.
+
(* Iop *)
- assert (eval_operation tge sp op rs##args = Some v).
+ exists (State s' (transf_code (analyze f) (fn_code f)) sp pc' (rs#res <- v) m); split.
+ assert (eval_operation tge sp op rs##args m = Some v).
rewrite <- H0. apply eval_operation_preserved. exact symbols_preserved.
+ generalize C; clear C.
case (is_trivial_op op).
intro. eapply exec_Iop'; eauto.
caseEq (find_op (analyze f)!!pc op args). intros r FIND CODE.
eapply exec_Iop'; eauto. simpl.
- assert (eval_operation ge sp op rs##args = Some rs#r).
+ assert (eval_operation ge sp op rs##args m = Some rs#r).
eapply find_op_correct; eauto.
eapply wf_analyze; eauto.
congruence.
- intros. eapply exec_Iop'; eauto.
+ intros. eapply exec_Iop'; eauto.
+ econstructor; eauto.
+ apply analysis_correct_1 with pc.
+ unfold successors; rewrite H; auto with coqlib.
+ unfold transfer; rewrite H.
+ eapply add_op_satisfiable; eauto. apply wf_analyze.
+
(* Iload *)
+ exists (State s' (transf_code (analyze f) (fn_code f)) sp pc' (rs#dst <- v) m); split.
assert (eval_addressing tge sp addr rs##args = Some a).
rewrite <- H0. apply eval_addressing_preserved. exact symbols_preserved.
+ generalize C; clear C.
caseEq (find_load (analyze f)!!pc chunk addr args). intros r FIND CODE.
eapply exec_Iop'; eauto. simpl.
assert (exists a, eval_addressing ge sp addr rs##args = Some a
@@ -862,52 +860,125 @@ Proof.
eapply wf_analyze; eauto.
elim H3; intros a' [A B].
congruence.
- intros. eapply exec_Iload'; eauto.
+ intros. eapply exec_Iload'; eauto.
+ econstructor; eauto.
+ apply analysis_correct_1 with pc.
+ unfold successors; rewrite H; auto with coqlib.
+ unfold transfer; rewrite H.
+ eapply add_load_satisfiable; eauto. apply wf_analyze.
+
(* Istore *)
+ exists (State s' (transf_code (analyze f) (fn_code f)) sp pc' rs m'); split.
assert (eval_addressing tge sp addr rs##args = Some a).
rewrite <- H0. apply eval_addressing_preserved. exact symbols_preserved.
- intro; eapply exec_Istore; eauto.
+ eapply exec_Istore; eauto.
+ econstructor; eauto.
+ apply analysis_correct_1 with pc.
+ unfold successors; rewrite H; auto with coqlib.
+ unfold transfer; rewrite H.
+ eapply kill_load_satisfiable; eauto.
+
(* Icall *)
- assert (find_function tge ros rs = Some (transf_fundef f)).
- destruct ros; simpl in H0; simpl.
- apply functions_translated; auto.
- rewrite symbols_preserved. destruct (Genv.find_symbol ge i).
- apply funct_ptr_translated; auto. discriminate.
- intro; eapply exec_Icall with (f := transf_fundef f); eauto.
- generalize (sig_translated f); congruence.
+ exploit find_function_translated; eauto. intro FIND'.
+ econstructor; split.
+ eapply exec_Icall with (f := transf_fundef f); eauto.
+ apply sig_preserved.
+ econstructor; eauto.
+ constructor; auto.
+ econstructor; eauto.
+ intros. apply analysis_correct_1 with pc.
+ unfold successors; rewrite H; auto with coqlib.
+ unfold transfer; rewrite H.
+ apply empty_numbering_satisfiable.
+
+ (* Itailcall *)
+ exploit find_function_translated; eauto. intro FIND'.
+ econstructor; split.
+ eapply exec_Itailcall with (f := transf_fundef f); eauto.
+ apply sig_preserved.
+ econstructor; eauto.
+
(* Ialloc *)
- intro; eapply exec_Ialloc; eauto.
+ exists (State s' (transf_code (analyze f) (fn_code f)) sp pc' (rs#res <- (Vptr b Int.zero)) m'); split.
+ eapply exec_Ialloc; eauto.
+ econstructor; eauto.
+ apply analysis_correct_1 with pc.
+ unfold successors; rewrite H; auto with coqlib.
+ unfold transfer; rewrite H.
+ apply add_unknown_satisfiable. apply wf_analyze; auto.
+ eapply alloc_satisfiable; eauto.
+
(* Icond true *)
- intro; eapply exec_Icond_true; eauto.
+ econstructor; split.
+ eapply exec_Icond_true; eauto.
+ econstructor; eauto.
+ apply analysis_correct_1 with pc.
+ unfold successors; rewrite H; auto with coqlib.
+ unfold transfer; rewrite H; auto.
+
(* Icond false *)
- intro; eapply exec_Icond_false; eauto.
- (* refl *)
- apply exec_refl.
- (* one *)
- apply exec_one; auto.
- (* trans *)
- eapply exec_trans; eauto. apply H2; auto.
- eapply analysis_correct_N; eauto.
+ econstructor; split.
+ eapply exec_Icond_false; eauto.
+ econstructor; eauto.
+ apply analysis_correct_1 with pc.
+ unfold successors; rewrite H; auto with coqlib.
+ unfold transfer; rewrite H; auto.
+
+ (* Ireturn *)
+ econstructor; split.
+ eapply exec_Ireturn; eauto.
+ constructor; auto.
+
(* internal function *)
- intro. unfold transf_function; simpl; eapply exec_funct_internal; simpl; eauto.
- eapply H1; eauto. eapply analysis_correct_entry; eauto.
+ simpl. econstructor; split.
+ eapply exec_function_internal; eauto.
+ simpl. econstructor; eauto.
+ apply analysis_correct_entry.
+
(* external function *)
- unfold transf_function; simpl. apply exec_funct_external; auto.
+ simpl. econstructor; split.
+ eapply exec_function_external; eauto.
+ econstructor; eauto.
+
+ (* return *)
+ inv H3. inv H1.
+ econstructor; split.
+ eapply exec_return; eauto.
+ econstructor; eauto.
+Qed.
+
+Lemma transf_initial_states:
+ forall st1, initial_state prog st1 ->
+ exists st2, initial_state tprog st2 /\ match_states st1 st2.
+Proof.
+ intros. inversion H.
+ exists (Callstate nil (transf_fundef f) nil (Genv.init_mem tprog)); split.
+ econstructor; eauto.
+ change (prog_main tprog) with (prog_main prog).
+ rewrite symbols_preserved. eauto.
+ apply funct_ptr_translated; auto.
+ rewrite <- H2. apply sig_preserved.
+ replace (Genv.init_mem tprog) with (Genv.init_mem prog).
+ constructor. constructor. auto.
+ symmetry. unfold tprog, transf_program. apply Genv.init_mem_transf.
+Qed.
+
+Lemma transf_final_states:
+ forall st1 st2 r,
+ match_states st1 st2 -> final_state st1 r -> final_state st2 r.
+Proof.
+ intros. inv H0. inv H. inv H4. constructor.
Qed.
Theorem transf_program_correct:
- forall (t: trace) (r: val),
- exec_program prog t r -> exec_program tprog t r.
-Proof.
- intros t r [fptr [f [m [FINDS [FINDF [SIG EXEC]]]]]].
- red. exists fptr; exists (transf_fundef f); exists m.
- split. change (prog_main tprog) with (prog_main prog).
- rewrite symbols_preserved. assumption.
- split. apply funct_ptr_translated; auto.
- split. generalize (sig_translated f); congruence.
- apply transf_function_correct.
- unfold tprog, transf_program. rewrite Genv.init_mem_transf.
- exact EXEC.
+ forall (beh: program_behavior),
+ exec_program prog beh -> exec_program tprog beh.
+Proof.
+ unfold exec_program; intros.
+ eapply simulation_step_preservation; eauto.
+ eexact transf_initial_states.
+ eexact transf_final_states.
+ exact transf_step_correct.
Qed.
End PRESERVATION.
diff --git a/backend/Cminor.v b/backend/Cminor.v
index 9ed5e19..2b9945a 100644
--- a/backend/Cminor.v
+++ b/backend/Cminor.v
@@ -8,41 +8,79 @@ Require Import Floats.
Require Import Events.
Require Import Values.
Require Import Mem.
-Require Import Op.
Require Import Globalenvs.
+Require Import Switch.
(** * Abstract syntax *)
(** Cminor is a low-level imperative language structured in expressions,
- statements, functions and programs. Expressions include
- reading local variables, reading and writing store locations,
- arithmetic operations, function calls, and conditional expressions
- (similar to [e1 ? e2 : e3] in C). The [Elet] and [Eletvar] constructs
- enable sharing the computations of subexpressions. De Bruijn notation
- is used: [Eletvar n] refers to the value bound by then [n+1]-th enclosing
- [Elet] construct.
-
- A variant [condexpr] of [expr] is used to represent expressions
- which are evaluated for their boolean value only and not their exact value.
-*)
+ statements, functions and programs. We first define the constants
+ and operators that occur within expressions. *)
+
+Inductive constant : Set :=
+ | Ointconst: int -> constant (**r integer constant *)
+ | Ofloatconst: float -> constant (**r floating-point constant *)
+ | Oaddrsymbol: ident -> int -> constant (**r address of the symbol plus the offset *)
+ | Oaddrstack: int -> constant. (**r stack pointer plus the given offset *)
+
+Inductive unary_operation : Set :=
+ | Ocast8unsigned: unary_operation (**r 8-bit zero extension *)
+ | Ocast8signed: unary_operation (**r 8-bit sign extension *)
+ | Ocast16unsigned: unary_operation (**r 16-bit zero extension *)
+ | Ocast16signed: unary_operation (**r 16-bit sign extension *)
+ | Onegint: unary_operation (**r integer opposite *)
+ | Onotbool: unary_operation (**r boolean negation *)
+ | Onotint: unary_operation (**r bitwise complement *)
+ | Onegf: unary_operation (**r float opposite *)
+ | Oabsf: unary_operation (**r float absolute value *)
+ | Osingleoffloat: unary_operation (**r float truncation *)
+ | Ointoffloat: unary_operation (**r integer to float *)
+ | Ofloatofint: unary_operation (**r float to signed integer *)
+ | Ofloatofintu: unary_operation. (**r float to unsigned integer *)
+
+Inductive binary_operation : Set :=
+ | Oadd: binary_operation (**r integer addition *)
+ | Osub: binary_operation (**r integer subtraction *)
+ | Omul: binary_operation (**r integer multiplication *)
+ | Odiv: binary_operation (**r integer signed division *)
+ | Odivu: binary_operation (**r integer unsigned division *)
+ | Omod: binary_operation (**r integer signed modulus *)
+ | Omodu: binary_operation (**r integer unsigned modulus *)
+ | Oand: binary_operation (**r bitwise ``and'' *)
+ | Oor: binary_operation (**r bitwise ``or'' *)
+ | Oxor: binary_operation (**r bitwise ``xor'' *)
+ | Oshl: binary_operation (**r left shift *)
+ | Oshr: binary_operation (**r right signed shift *)
+ | Oshru: binary_operation (**r right unsigned shift *)
+ | Oaddf: binary_operation (**r float addition *)
+ | Osubf: binary_operation (**r float subtraction *)
+ | Omulf: binary_operation (**r float multiplication *)
+ | Odivf: binary_operation (**r float division *)
+ | Ocmp: comparison -> binary_operation (**r integer signed comparison *)
+ | Ocmpu: comparison -> binary_operation (**r integer unsigned comparison *)
+ | Ocmpf: comparison -> binary_operation. (**r float comparison *)
+
+(** Expressions include reading local variables, constants and
+ arithmetic operations, reading and writing store locations,
+ function calls, and conditional expressions
+ (similar to [e1 ? e2 : e3] in C).
+ The [Elet] and [Eletvar] constructs enable sharing the computations
+ of subexpressions. De Bruijn notation is used: [Eletvar n] refers
+ to the value bound by then [n+1]-th enclosing [Elet] construct. *)
Inductive expr : Set :=
| Evar : ident -> expr
- | Eop : operation -> exprlist -> expr
- | Eload : memory_chunk -> addressing -> exprlist -> expr
- | Estore : memory_chunk -> addressing -> exprlist -> expr -> expr
+ | Econst : constant -> expr
+ | Eunop : unary_operation -> expr -> expr
+ | Ebinop : binary_operation -> expr -> expr -> expr
+ | Eload : memory_chunk -> expr -> expr
+ | Estore : memory_chunk -> expr -> expr -> expr
| Ecall : signature -> expr -> exprlist -> expr
- | Econdition : condexpr -> expr -> expr -> expr
+ | Econdition : expr -> expr -> expr -> expr
| Elet : expr -> expr -> expr
| Eletvar : nat -> expr
| Ealloc : expr -> expr
-with condexpr : Set :=
- | CEtrue: condexpr
- | CEfalse: condexpr
- | CEcond: condition -> exprlist -> condexpr
- | CEcondition : condexpr -> condexpr -> condexpr -> condexpr
-
with exprlist : Set :=
| Enil: exprlist
| Econs: expr -> exprlist -> exprlist.
@@ -57,12 +95,13 @@ Inductive stmt : Set :=
| Sexpr: expr -> stmt
| Sassign : ident -> expr -> stmt
| Sseq: stmt -> stmt -> stmt
- | Sifthenelse: condexpr -> stmt -> stmt -> stmt
+ | Sifthenelse: expr -> stmt -> stmt -> stmt
| Sloop: stmt -> stmt
| Sblock: stmt -> stmt
| Sexit: nat -> stmt
| Sswitch: expr -> list (int * nat) -> nat -> stmt
- | Sreturn: option expr -> stmt.
+ | Sreturn: option expr -> stmt
+ | Stailcall: signature -> expr -> exprlist -> stmt.
(** Functions are composed of a signature, a list of parameter names,
a list of local variables, and a statement representing
@@ -97,30 +136,31 @@ Definition funsig (fd: fundef) :=
Inductive outcome: Set :=
| Out_normal: outcome (**r continue in sequence *)
| Out_exit: nat -> outcome (**r terminate [n+1] enclosing blocks *)
- | Out_return: option val -> outcome. (**r return immediately to caller *)
-
-Definition outcome_result_value
- (out: outcome) (ot: option typ) (v: val) : Prop :=
- match out, ot with
- | Out_normal, None => v = Vundef
- | Out_return None, None => v = Vundef
- | Out_return (Some v'), Some ty => v = v'
- | _, _ => False
- end.
+ | Out_return: option val -> outcome (**r return immediately to caller *)
+ | Out_tailcall_return: val -> outcome. (**r already returned to caller via a tailcall *)
Definition outcome_block (out: outcome) : outcome :=
match out with
- | Out_normal => Out_normal
| Out_exit O => Out_normal
| Out_exit (S n) => Out_exit n
- | Out_return optv => Out_return optv
+ | out => out
+ end.
+
+Definition outcome_result_value
+ (out: outcome) (retsig: option typ) (vres: val) : Prop :=
+ match out, retsig with
+ | Out_normal, None => vres = Vundef
+ | Out_return None, None => vres = Vundef
+ | Out_return (Some v), Some ty => vres = v
+ | Out_tailcall_return v, _ => vres = v
+ | _, _ => False
end.
-Fixpoint switch_target (n: int) (dfl: nat) (cases: list (int * nat))
- {struct cases} : nat :=
- match cases with
- | nil => dfl
- | (n1, lbl1) :: rem => if Int.eq n n1 then lbl1 else switch_target n dfl rem
+Definition outcome_free_mem
+ (out: outcome) (m: mem) (sp: block) : mem :=
+ match out with
+ | Out_tailcall_return _ => m
+ | _ => Mem.free m sp
end.
(** Three kinds of evaluation environments are involved:
@@ -154,10 +194,105 @@ Section RELSEM.
Variable ge: genv.
-(** Evaluation of an expression: [eval_expr ge sp le e m a m' v]
+(** Evaluation of constants and operator applications.
+ [None] is returned when the computation is undefined, e.g.
+ if arguments are of the wrong types, or in case of an integer division
+ by zero. *)
+
+Definition eval_constant (sp: val) (cst: constant) : option val :=
+ match cst with
+ | Ointconst n => Some (Vint n)
+ | Ofloatconst n => Some (Vfloat n)
+ | Oaddrsymbol s ofs =>
+ match Genv.find_symbol ge s with
+ | None => None
+ | Some b => Some (Vptr b ofs)
+ end
+ | Oaddrstack ofs =>
+ match sp with
+ | Vptr b n => Some (Vptr b (Int.add n ofs))
+ | _ => None
+ end
+ end.
+
+Definition eval_unop (op: unary_operation) (arg: val) : option val :=
+ match op, arg with
+ | Ocast8unsigned, _ => Some (Val.cast8unsigned arg)
+ | Ocast8signed, _ => Some (Val.cast8signed arg)
+ | Ocast16unsigned, _ => Some (Val.cast16unsigned arg)
+ | Ocast16signed, _ => Some (Val.cast16signed arg)
+ | Onegint, Vint n1 => Some (Vint (Int.neg n1))
+ | Onotbool, Vint n1 => Some (Val.of_bool (Int.eq n1 Int.zero))
+ | Onotbool, Vptr b1 n1 => Some Vfalse
+ | Onotint, Vint n1 => Some (Vint (Int.not n1))
+ | Onegf, Vfloat f1 => Some (Vfloat (Float.neg f1))
+ | Oabsf, Vfloat f1 => Some (Vfloat (Float.abs f1))
+ | Osingleoffloat, _ => Some (Val.singleoffloat arg)
+ | Ointoffloat, Vfloat f1 => Some (Vint (Float.intoffloat f1))
+ | Ofloatofint, Vint n1 => Some (Vfloat (Float.floatofint n1))
+ | Ofloatofintu, Vint n1 => Some (Vfloat (Float.floatofintu n1))
+ | _, _ => None
+ end.
+
+Definition eval_compare_null (c: comparison) (n: int) : option val :=
+ if Int.eq n Int.zero
+ then match c with Ceq => Some Vfalse | Cne => Some Vtrue | _ => None end
+ else None.
+
+Definition eval_binop
+ (op: binary_operation) (arg1 arg2: val) (m: mem): option val :=
+ match op, arg1, arg2 with
+ | Oadd, Vint n1, Vint n2 => Some (Vint (Int.add n1 n2))
+ | Oadd, Vint n1, Vptr b2 n2 => Some (Vptr b2 (Int.add n2 n1))
+ | Oadd, Vptr b1 n1, Vint n2 => Some (Vptr b1 (Int.add n1 n2))
+ | Osub, Vint n1, Vint n2 => Some (Vint (Int.sub n1 n2))
+ | Osub, Vptr b1 n1, Vint n2 => Some (Vptr b1 (Int.sub n1 n2))
+ | Osub, Vptr b1 n1, Vptr b2 n2 =>
+ if eq_block b1 b2 then Some (Vint (Int.sub n1 n2)) else None
+ | Omul, Vint n1, Vint n2 => Some (Vint (Int.mul n1 n2))
+ | Odiv, Vint n1, Vint n2 =>
+ if Int.eq n2 Int.zero then None else Some (Vint (Int.divs n1 n2))
+ | Odivu, Vint n1, Vint n2 =>
+ if Int.eq n2 Int.zero then None else Some (Vint (Int.divu n1 n2))
+ | Omod, Vint n1, Vint n2 =>
+ if Int.eq n2 Int.zero then None else Some (Vint (Int.mods n1 n2))
+ | Omodu, Vint n1, Vint n2 =>
+ if Int.eq n2 Int.zero then None else Some (Vint (Int.modu n1 n2))
+ | Oand, Vint n1, Vint n2 => Some (Vint (Int.and n1 n2))
+ | Oor, Vint n1, Vint n2 => Some (Vint (Int.or n1 n2))
+ | Oxor, Vint n1, Vint n2 => Some (Vint (Int.xor n1 n2))
+ | Oshl, Vint n1, Vint n2 =>
+ if Int.ltu n2 (Int.repr 32) then Some (Vint (Int.shl n1 n2)) else None
+ | Oshr, Vint n1, Vint n2 =>
+ if Int.ltu n2 (Int.repr 32) then Some (Vint (Int.shr n1 n2)) else None
+ | Oshru, Vint n1, Vint n2 =>
+ if Int.ltu n2 (Int.repr 32) then Some (Vint (Int.shru n1 n2)) else None
+ | Oaddf, Vfloat f1, Vfloat f2 => Some (Vfloat (Float.add f1 f2))
+ | Osubf, Vfloat f1, Vfloat f2 => Some (Vfloat (Float.sub f1 f2))
+ | Omulf, Vfloat f1, Vfloat f2 => Some (Vfloat (Float.mul f1 f2))
+ | Odivf, Vfloat f1, Vfloat f2 => Some (Vfloat (Float.div f1 f2))
+ | Ocmp c, Vint n1, Vint n2 =>
+ Some (Val.of_bool(Int.cmp c n1 n2))
+ | Ocmp c, Vptr b1 n1, Vptr b2 n2 =>
+ if valid_pointer m b1 (Int.signed n1)
+ && valid_pointer m b2 (Int.signed n2) then
+ if eq_block b1 b2 then Some(Val.of_bool(Int.cmp c n1 n2)) else None
+ else
+ None
+ | Ocmp c, Vptr b1 n1, Vint n2 => eval_compare_null c n2
+ | Ocmp c, Vint n1, Vptr b2 n2 => eval_compare_null c n1
+ | Ocmpu c, Vint n1, Vint n2 =>
+ Some (Val.of_bool(Int.cmpu c n1 n2))
+ | Ocmpf c, Vfloat f1, Vfloat f2 =>
+ Some (Val.of_bool (Float.cmp c f1 f2))
+ | _, _, _ => None
+ end.
+
+(** Evaluation of an expression: [eval_expr ge sp le e m a t m' v]
states that expression [a], in initial local environment [e] and
memory state [m], evaluates to value [v]. [m'] is the final
memory state, reflecting memory stores possibly performed by [a].
+ [t] is the trace of I/O events generated during the evaluation.
Expressions do not assign variables, therefore the local environment
[e] is unchanged. [ge] and [le] are the global environment and let
environment respectively, and are unchanged during evaluation. [sp]
@@ -172,25 +307,34 @@ Inductive eval_expr:
forall sp le e m id v,
PTree.get id e = Some v ->
eval_expr sp le e m (Evar id) E0 m v
- | eval_Eop:
- forall sp le e m op al t m1 vl v,
- eval_exprlist sp le e m al t m1 vl ->
- eval_operation ge sp op vl = Some v ->
- eval_expr sp le e m (Eop op al) t m1 v
+ | eval_Econst:
+ forall sp le e m cst v,
+ eval_constant sp cst = Some v ->
+ eval_expr sp le e m (Econst cst) E0 m v
+ | eval_Eunop:
+ forall sp le e m op a t m1 v1 v,
+ eval_expr sp le e m a t m1 v1 ->
+ eval_unop op v1 = Some v ->
+ eval_expr sp le e m (Eunop op a) t m1 v
+ | eval_Ebinop:
+ forall sp le e m op a1 a2 t1 m1 v1 t2 m2 v2 t v,
+ eval_expr sp le e m a1 t1 m1 v1 ->
+ eval_expr sp le e m1 a2 t2 m2 v2 ->
+ eval_binop op v1 v2 m2 = Some v ->
+ t = t1 ** t2 ->
+ eval_expr sp le e m (Ebinop op a1 a2) t m2 v
| eval_Eload:
- forall sp le e m chunk addr al t m1 v vl a,
- eval_exprlist sp le e m al t m1 vl ->
- eval_addressing ge sp addr vl = Some a ->
- Mem.loadv chunk m1 a = Some v ->
- eval_expr sp le e m (Eload chunk addr al) t m1 v
+ forall sp le e m chunk a t m1 v1 v,
+ eval_expr sp le e m a t m1 v1 ->
+ Mem.loadv chunk m1 v1 = Some v ->
+ eval_expr sp le e m (Eload chunk a) t m1 v
| eval_Estore:
- forall sp le e m chunk addr al b t t1 m1 vl t2 m2 m3 v a,
- eval_exprlist sp le e m al t1 m1 vl ->
- eval_expr sp le e m1 b t2 m2 v ->
- eval_addressing ge sp addr vl = Some a ->
- Mem.storev chunk m2 a v = Some m3 ->
+ forall sp le e m chunk a1 a2 t t1 m1 v1 t2 m2 v2 m3,
+ eval_expr sp le e m a1 t1 m1 v1 ->
+ eval_expr sp le e m1 a2 t2 m2 v2 ->
+ Mem.storev chunk m2 v1 v2 = Some m3 ->
t = t1 ** t2 ->
- eval_expr sp le e m (Estore chunk addr al b) t m3 v
+ eval_expr sp le e m (Estore chunk a1 a2) t m3 v2
| eval_Ecall:
forall sp le e m sig a bl t t1 m1 t2 m2 t3 m3 vf vargs vres f,
eval_expr sp le e m a t1 m1 vf ->
@@ -201,11 +345,12 @@ Inductive eval_expr:
t = t1 ** t2 ** t3 ->
eval_expr sp le e m (Ecall sig a bl) t m3 vres
| eval_Econdition:
- forall sp le e m a b c t t1 m1 v1 t2 m2 v2,
- eval_condexpr sp le e m a t1 m1 v1 ->
- eval_expr sp le e m1 (if v1 then b else c) t2 m2 v2 ->
+ forall sp le e m a1 a2 a3 t t1 m1 v1 b1 t2 m2 v2,
+ eval_expr sp le e m a1 t1 m1 v1 ->
+ Val.bool_of_val v1 b1 ->
+ eval_expr sp le e m1 (if b1 then a2 else a3) t2 m2 v2 ->
t = t1 ** t2 ->
- eval_expr sp le e m (Econdition a b c) t m2 v2
+ eval_expr sp le e m (Econdition a1 a2 a3) t m2 v2
| eval_Elet:
forall sp le e m a b t t1 m1 v1 t2 m2 v2,
eval_expr sp le e m a t1 m1 v1 ->
@@ -222,33 +367,6 @@ Inductive eval_expr:
Mem.alloc m1 0 (Int.signed n) = (m2, b) ->
eval_expr sp le e m (Ealloc a) t m2 (Vptr b Int.zero)
-(** Evaluation of a condition expression:
- [eval_condexpr ge sp le e m a m' b]
- states that condition expression [a] evaluates to the boolean value [b].
- The other parameters are as in [eval_expr].
-*)
-
-with eval_condexpr:
- val -> letenv -> env ->
- mem -> condexpr -> trace -> mem -> bool -> Prop :=
- | eval_CEtrue:
- forall sp le e m,
- eval_condexpr sp le e m CEtrue E0 m true
- | eval_CEfalse:
- forall sp le e m,
- eval_condexpr sp le e m CEfalse E0 m false
- | eval_CEcond:
- forall sp le e m cond al t1 m1 vl b,
- eval_exprlist sp le e m al t1 m1 vl ->
- eval_condition cond vl = Some b ->
- eval_condexpr sp le e m (CEcond cond al) t1 m1 b
- | eval_CEcondition:
- forall sp le e m a b c t t1 m1 vb1 t2 m2 vb2,
- eval_condexpr sp le e m a t1 m1 vb1 ->
- eval_condexpr sp le e m1 (if vb1 then b else c) t2 m2 vb2 ->
- t = t1 ** t2 ->
- eval_condexpr sp le e m (CEcondition a b c) t m2 vb2
-
(** Evaluation of a list of expressions:
[eval_exprlist ge sp le al m a m' vl]
states that the list [al] of expressions evaluate
@@ -272,6 +390,7 @@ with eval_exprlist:
(** Evaluation of a function invocation: [eval_funcall ge m f args m' res]
means that the function [f], applied to the arguments [args] in
memory state [m], returns the value [res] in modified memory state [m'].
+ [t] is the trace of observable events generated during the invocation.
*)
with eval_funcall:
@@ -283,7 +402,7 @@ with eval_funcall:
set_locals f.(fn_vars) (set_params vargs f.(fn_params)) = e ->
exec_stmt (Vptr sp Int.zero) e m1 f.(fn_body) t e2 m2 out ->
outcome_result_value out f.(fn_sig).(sig_res) vres ->
- eval_funcall m (Internal f) vargs t (Mem.free m2 sp) vres
+ eval_funcall m (Internal f) vargs t (outcome_free_mem out m2 sp) vres
| eval_funcall_external:
forall ef m args t res,
event_match ef args t res ->
@@ -291,7 +410,10 @@ with eval_funcall:
(** Execution of a statement: [exec_stmt ge sp e m s e' m' out]
means that statement [s] executes with outcome [out].
- The other parameters are as in [eval_expr]. *)
+ [e] is the initial environment and [m] is the initial memory state.
+ [e'] is the final environment, reflecting variable assignments performed
+ by [s]. [m'] is the final memory state, reflecting memory stores
+ performed by [s]. The other parameters are as in [eval_expr]. *)
with exec_stmt:
val ->
@@ -309,9 +431,10 @@ with exec_stmt:
eval_expr sp nil e m a t m1 v ->
exec_stmt sp e m (Sassign id a) t (PTree.set id v e) m1 Out_normal
| exec_Sifthenelse:
- forall sp e m a s1 s2 t t1 m1 v1 t2 e2 m2 out,
- eval_condexpr sp nil e m a t1 m1 v1 ->
- exec_stmt sp e m1 (if v1 then s1 else s2) t2 e2 m2 out ->
+ forall sp e m a s1 s2 t t1 m1 v1 b1 t2 e2 m2 out,
+ eval_expr sp nil e m a t1 m1 v1 ->
+ Val.bool_of_val v1 b1 ->
+ exec_stmt sp e m1 (if b1 then s1 else s2) t2 e2 m2 out ->
t = t1 ** t2 ->
exec_stmt sp e m (Sifthenelse a s1 s2) t e2 m2 out
| exec_Sseq_continue:
@@ -354,13 +477,29 @@ with exec_stmt:
| exec_Sreturn_some:
forall sp e m a t m1 v,
eval_expr sp nil e m a t m1 v ->
- exec_stmt sp e m (Sreturn (Some a)) t e m1 (Out_return (Some v)).
+ exec_stmt sp e m (Sreturn (Some a)) t e m1 (Out_return (Some v))
+ | exec_Stailcall:
+ forall sp e m sig a bl t t1 m1 t2 m2 t3 m3 vf vargs vres f,
+ eval_expr (Vptr sp Int.zero) nil e m a t1 m1 vf ->
+ eval_exprlist (Vptr sp Int.zero) nil e m1 bl t2 m2 vargs ->
+ Genv.find_funct ge vf = Some f ->
+ funsig f = sig ->
+ eval_funcall (Mem.free m2 sp) f vargs t3 m3 vres ->
+ t = t1 ** t2 ** t3 ->
+ exec_stmt (Vptr sp Int.zero) e m (Stailcall sig a bl) t e m3 (Out_tailcall_return vres).
+
+Scheme eval_expr_ind4 := Minimality for eval_expr Sort Prop
+ with eval_exprlist_ind4 := Minimality for eval_exprlist Sort Prop
+ with eval_funcall_ind4 := Minimality for eval_funcall Sort Prop
+ with exec_stmt_ind4 := Minimality for exec_stmt Sort Prop.
End RELSEM.
-(** Execution of a whole program: [exec_program p r]
+(** Execution of a whole program: [exec_program p t r]
holds if the application of [p]'s main function to no arguments
- in the initial memory state for [p] eventually returns value [r]. *)
+ in the initial memory state for [p] performs the input/output
+ operations described in the trace [t], and eventually returns value [r].
+*)
Definition exec_program (p: program) (t: trace) (r: val) : Prop :=
let ge := Genv.globalenv p in
diff --git a/backend/CminorSel.v b/backend/CminorSel.v
new file mode 100644
index 0000000..331105e
--- /dev/null
+++ b/backend/CminorSel.v
@@ -0,0 +1,296 @@
+(** The Cminor language after instruction selection. *)
+
+Require Import Coqlib.
+Require Import Maps.
+Require Import AST.
+Require Import Integers.
+Require Import Floats.
+Require Import Events.
+Require Import Values.
+Require Import Mem.
+Require Import Cminor.
+Require Import Op.
+Require Import Globalenvs.
+Require Import Switch.
+
+(** * Abstract syntax *)
+
+(** CminorSel programs share the general structure of Cminor programs:
+ functions, statements and expressions. However, CminorSel uses
+ machine-dependent operations, addressing modes and conditions,
+ as defined in module [Op] and used in lower-level intermediate
+ languages ([RTL] and below). Moreover, a variant [condexpr] of [expr]
+ is used to represent expressions which are evaluated for their
+ boolean value only and not their exact value.
+*)
+
+Inductive expr : Set :=
+ | Evar : ident -> expr
+ | Eop : operation -> exprlist -> expr
+ | Eload : memory_chunk -> addressing -> exprlist -> expr
+ | Estore : memory_chunk -> addressing -> exprlist -> expr -> expr
+ | Ecall : signature -> expr -> exprlist -> expr
+ | Econdition : condexpr -> expr -> expr -> expr
+ | Elet : expr -> expr -> expr
+ | Eletvar : nat -> expr
+ | Ealloc : expr -> expr
+
+with condexpr : Set :=
+ | CEtrue: condexpr
+ | CEfalse: condexpr
+ | CEcond: condition -> exprlist -> condexpr
+ | CEcondition : condexpr -> condexpr -> condexpr -> condexpr
+
+with exprlist : Set :=
+ | Enil: exprlist
+ | Econs: expr -> exprlist -> exprlist.
+
+(** Statements are as in Cminor, except that the condition of an
+ if/then/else conditional is a [condexpr]. *)
+
+Inductive stmt : Set :=
+ | Sskip: stmt
+ | Sexpr: expr -> stmt
+ | Sassign : ident -> expr -> stmt
+ | Sseq: stmt -> stmt -> stmt
+ | Sifthenelse: condexpr -> stmt -> stmt -> stmt
+ | Sloop: stmt -> stmt
+ | Sblock: stmt -> stmt
+ | Sexit: nat -> stmt
+ | Sswitch: expr -> list (int * nat) -> nat -> stmt
+ | Sreturn: option expr -> stmt
+ | Stailcall: signature -> expr -> exprlist -> stmt.
+
+Record function : Set := mkfunction {
+ fn_sig: signature;
+ fn_params: list ident;
+ fn_vars: list ident;
+ fn_stackspace: Z;
+ fn_body: stmt
+}.
+
+Definition fundef := AST.fundef function.
+Definition program := AST.program fundef unit.
+
+Definition funsig (fd: fundef) :=
+ match fd with
+ | Internal f => f.(fn_sig)
+ | External ef => ef.(ef_sig)
+ end.
+
+(** * Operational semantics *)
+
+(** Three kinds of evaluation environments are involved:
+- [genv]: global environments, define symbols and functions;
+- [env]: local environments, map local variables to values;
+- [lenv]: let environments, map de Bruijn indices to values.
+*)
+
+Definition genv := Genv.t fundef.
+
+Section RELSEM.
+
+Variable ge: genv.
+
+(** The evaluation predicates have the same general shape as those
+ of Cminor. Refer to the description of Cminor semantics for
+ the meaning of the parameters of the predicates.
+ One additional predicate is introduced:
+ [eval_condexpr ge sp le e m a t m' b], meaning that the conditional
+ expression [a] evaluates to the boolean [b]. *)
+
+Inductive eval_expr:
+ val -> letenv -> env ->
+ mem -> expr -> trace -> mem -> val -> Prop :=
+ | eval_Evar:
+ forall sp le e m id v,
+ PTree.get id e = Some v ->
+ eval_expr sp le e m (Evar id) E0 m v
+ | eval_Eop:
+ forall sp le e m op al t m1 vl v,
+ eval_exprlist sp le e m al t m1 vl ->
+ eval_operation ge sp op vl m1 = Some v ->
+ eval_expr sp le e m (Eop op al) t m1 v
+ | eval_Eload:
+ forall sp le e m chunk addr al t m1 v vl a,
+ eval_exprlist sp le e m al t m1 vl ->
+ eval_addressing ge sp addr vl = Some a ->
+ Mem.loadv chunk m1 a = Some v ->
+ eval_expr sp le e m (Eload chunk addr al) t m1 v
+ | eval_Estore:
+ forall sp le e m chunk addr al b t t1 m1 vl t2 m2 m3 v a,
+ eval_exprlist sp le e m al t1 m1 vl ->
+ eval_expr sp le e m1 b t2 m2 v ->
+ eval_addressing ge sp addr vl = Some a ->
+ Mem.storev chunk m2 a v = Some m3 ->
+ t = t1 ** t2 ->
+ eval_expr sp le e m (Estore chunk addr al b) t m3 v
+ | eval_Ecall:
+ forall sp le e m sig a bl t t1 m1 t2 m2 t3 m3 vf vargs vres f,
+ eval_expr sp le e m a t1 m1 vf ->
+ eval_exprlist sp le e m1 bl t2 m2 vargs ->
+ Genv.find_funct ge vf = Some f ->
+ funsig f = sig ->
+ eval_funcall m2 f vargs t3 m3 vres ->
+ t = t1 ** t2 ** t3 ->
+ eval_expr sp le e m (Ecall sig a bl) t m3 vres
+ | eval_Econdition:
+ forall sp le e m a b c t t1 m1 v1 t2 m2 v2,
+ eval_condexpr sp le e m a t1 m1 v1 ->
+ eval_expr sp le e m1 (if v1 then b else c) t2 m2 v2 ->
+ t = t1 ** t2 ->
+ eval_expr sp le e m (Econdition a b c) t m2 v2
+ | eval_Elet:
+ forall sp le e m a b t t1 m1 v1 t2 m2 v2,
+ eval_expr sp le e m a t1 m1 v1 ->
+ eval_expr sp (v1::le) e m1 b t2 m2 v2 ->
+ t = t1 ** t2 ->
+ eval_expr sp le e m (Elet a b) t m2 v2
+ | eval_Eletvar:
+ forall sp le e m n v,
+ nth_error le n = Some v ->
+ eval_expr sp le e m (Eletvar n) E0 m v
+ | eval_Ealloc:
+ forall sp le e m a t m1 n m2 b,
+ eval_expr sp le e m a t m1 (Vint n) ->
+ Mem.alloc m1 0 (Int.signed n) = (m2, b) ->
+ eval_expr sp le e m (Ealloc a) t m2 (Vptr b Int.zero)
+
+with eval_condexpr:
+ val -> letenv -> env ->
+ mem -> condexpr -> trace -> mem -> bool -> Prop :=
+ | eval_CEtrue:
+ forall sp le e m,
+ eval_condexpr sp le e m CEtrue E0 m true
+ | eval_CEfalse:
+ forall sp le e m,
+ eval_condexpr sp le e m CEfalse E0 m false
+ | eval_CEcond:
+ forall sp le e m cond al t1 m1 vl b,
+ eval_exprlist sp le e m al t1 m1 vl ->
+ eval_condition cond vl m1 = Some b ->
+ eval_condexpr sp le e m (CEcond cond al) t1 m1 b
+ | eval_CEcondition:
+ forall sp le e m a b c t t1 m1 vb1 t2 m2 vb2,
+ eval_condexpr sp le e m a t1 m1 vb1 ->
+ eval_condexpr sp le e m1 (if vb1 then b else c) t2 m2 vb2 ->
+ t = t1 ** t2 ->
+ eval_condexpr sp le e m (CEcondition a b c) t m2 vb2
+
+with eval_exprlist:
+ val -> letenv -> env ->
+ mem -> exprlist -> trace -> mem -> list val -> Prop :=
+ | eval_Enil:
+ forall sp le e m,
+ eval_exprlist sp le e m Enil E0 m nil
+ | eval_Econs:
+ forall sp le e m a bl t t1 m1 v t2 m2 vl,
+ eval_expr sp le e m a t1 m1 v ->
+ eval_exprlist sp le e m1 bl t2 m2 vl ->
+ t = t1 ** t2 ->
+ eval_exprlist sp le e m (Econs a bl) t m2 (v :: vl)
+
+with eval_funcall:
+ mem -> fundef -> list val -> trace ->
+ mem -> val -> Prop :=
+ | eval_funcall_internal:
+ forall m f vargs m1 sp e t e2 m2 out vres,
+ Mem.alloc m 0 f.(fn_stackspace) = (m1, sp) ->
+ set_locals f.(fn_vars) (set_params vargs f.(fn_params)) = e ->
+ exec_stmt (Vptr sp Int.zero) e m1 f.(fn_body) t e2 m2 out ->
+ outcome_result_value out f.(fn_sig).(sig_res) vres ->
+ eval_funcall m (Internal f) vargs t (outcome_free_mem out m2 sp) vres
+ | eval_funcall_external:
+ forall ef m args t res,
+ event_match ef args t res ->
+ eval_funcall m (External ef) args t m res
+
+with exec_stmt:
+ val ->
+ env -> mem -> stmt -> trace ->
+ env -> mem -> outcome -> Prop :=
+ | exec_Sskip:
+ forall sp e m,
+ exec_stmt sp e m Sskip E0 e m Out_normal
+ | exec_Sexpr:
+ forall sp e m a t m1 v,
+ eval_expr sp nil e m a t m1 v ->
+ exec_stmt sp e m (Sexpr a) t e m1 Out_normal
+ | exec_Sassign:
+ forall sp e m id a t m1 v,
+ eval_expr sp nil e m a t m1 v ->
+ exec_stmt sp e m (Sassign id a) t (PTree.set id v e) m1 Out_normal
+ | exec_Sifthenelse:
+ forall sp e m a s1 s2 t t1 m1 v1 t2 e2 m2 out,
+ eval_condexpr sp nil e m a t1 m1 v1 ->
+ exec_stmt sp e m1 (if v1 then s1 else s2) t2 e2 m2 out ->
+ t = t1 ** t2 ->
+ exec_stmt sp e m (Sifthenelse a s1 s2) t e2 m2 out
+ | exec_Sseq_continue:
+ forall sp e m t s1 t1 e1 m1 s2 t2 e2 m2 out,
+ exec_stmt sp e m s1 t1 e1 m1 Out_normal ->
+ exec_stmt sp e1 m1 s2 t2 e2 m2 out ->
+ t = t1 ** t2 ->
+ exec_stmt sp e m (Sseq s1 s2) t e2 m2 out
+ | exec_Sseq_stop:
+ forall sp e m t s1 s2 e1 m1 out,
+ exec_stmt sp e m s1 t e1 m1 out ->
+ out <> Out_normal ->
+ exec_stmt sp e m (Sseq s1 s2) t e1 m1 out
+ | exec_Sloop_loop:
+ forall sp e m s t t1 e1 m1 t2 e2 m2 out,
+ exec_stmt sp e m s t1 e1 m1 Out_normal ->
+ exec_stmt sp e1 m1 (Sloop s) t2 e2 m2 out ->
+ t = t1 ** t2 ->
+ exec_stmt sp e m (Sloop s) t e2 m2 out
+ | exec_Sloop_stop:
+ forall sp e m t s e1 m1 out,
+ exec_stmt sp e m s t e1 m1 out ->
+ out <> Out_normal ->
+ exec_stmt sp e m (Sloop s) t e1 m1 out
+ | exec_Sblock:
+ forall sp e m s t e1 m1 out,
+ exec_stmt sp e m s t e1 m1 out ->
+ exec_stmt sp e m (Sblock s) t e1 m1 (outcome_block out)
+ | exec_Sexit:
+ forall sp e m n,
+ exec_stmt sp e m (Sexit n) E0 e m (Out_exit n)
+ | exec_Sswitch:
+ forall sp e m a cases default t1 m1 n,
+ eval_expr sp nil e m a t1 m1 (Vint n) ->
+ exec_stmt sp e m (Sswitch a cases default)
+ t1 e m1 (Out_exit (switch_target n default cases))
+ | exec_Sreturn_none:
+ forall sp e m,
+ exec_stmt sp e m (Sreturn None) E0 e m (Out_return None)
+ | exec_Sreturn_some:
+ forall sp e m a t m1 v,
+ eval_expr sp nil e m a t m1 v ->
+ exec_stmt sp e m (Sreturn (Some a)) t e m1 (Out_return (Some v))
+ | exec_Stailcall:
+ forall sp e m sig a bl t t1 m1 t2 m2 t3 m3 vf vargs vres f,
+ eval_expr (Vptr sp Int.zero) nil e m a t1 m1 vf ->
+ eval_exprlist (Vptr sp Int.zero) nil e m1 bl t2 m2 vargs ->
+ Genv.find_funct ge vf = Some f ->
+ funsig f = sig ->
+ eval_funcall (Mem.free m2 sp) f vargs t3 m3 vres ->
+ t = t1 ** t2 ** t3 ->
+ exec_stmt (Vptr sp Int.zero) e m (Stailcall sig a bl) t e m3 (Out_tailcall_return vres).
+
+Scheme eval_expr_ind5 := Minimality for eval_expr Sort Prop
+ with eval_condexpr_ind5 := Minimality for eval_condexpr Sort Prop
+ with eval_exprlist_ind5 := Minimality for eval_exprlist Sort Prop
+ with eval_funcall_ind5 := Minimality for eval_funcall Sort Prop
+ with exec_stmt_ind5 := Minimality for exec_stmt Sort Prop.
+
+End RELSEM.
+
+Definition exec_program (p: program) (t: trace) (r: val) : Prop :=
+ let ge := Genv.globalenv p in
+ let m0 := Genv.init_mem p in
+ exists b, exists f, exists m,
+ Genv.find_symbol ge p.(prog_main) = Some b /\
+ Genv.find_funct_ptr ge b = Some f /\
+ funsig f = mksignature nil (Some Tint) /\
+ eval_funcall ge m0 f nil t m r.
+
diff --git a/backend/Coloring.v b/backend/Coloring.v
index 0b8a4cc..57f7d59 100644
--- a/backend/Coloring.v
+++ b/backend/Coloring.v
@@ -150,6 +150,8 @@ Definition add_edges_instr
(add_interf_op res live
(add_interf_call
(Regset.remove res live) destroyed_at_call_regs g)))
+ | Itailcall sig ros args =>
+ add_prefs_call args (loc_arguments sig) g
| Ialloc arg res s =>
add_pref_mreg arg loc_alloc_argument
(add_pref_mreg res loc_alloc_result
diff --git a/backend/Coloringproof.v b/backend/Coloringproof.v
index f3801d0..ce24030 100644
--- a/backend/Coloringproof.v
+++ b/backend/Coloringproof.v
@@ -325,6 +325,7 @@ Proof.
eapply graph_incl_trans; [idtac|apply add_pref_mreg_incl].
eapply graph_incl_trans; [idtac|apply add_interf_op_incl].
apply add_interf_call_incl.
+ apply add_prefs_call_incl.
eapply graph_incl_trans; [idtac|apply add_pref_mreg_incl].
eapply graph_incl_trans; [idtac|apply add_pref_mreg_incl].
eapply graph_incl_trans; [idtac|apply add_interf_op_incl].
diff --git a/backend/Constprop.v b/backend/Constprop.v
index d34c6ee..fecfb19 100644
--- a/backend/Constprop.v
+++ b/backend/Constprop.v
@@ -632,6 +632,8 @@ Definition transfer (f: function) (pc: node) (before: D.t) :=
before
| Icall sig ros args res s =>
D.set res Unknown before
+ | Itailcall sig ros args =>
+ before
| Ialloc arg res s =>
D.set res Unknown before
| Icond cond args ifso ifnot =>
@@ -649,9 +651,12 @@ Definition transfer (f: function) (pc: node) (before: D.t) :=
Module DS := Dataflow_Solver(D)(NodeSetForward).
-Definition analyze (f: RTL.function): option (PMap.t D.t) :=
- DS.fixpoint (successors f) f.(fn_nextpc) (transfer f)
- ((f.(fn_entrypoint), D.top) :: nil).
+Definition analyze (f: RTL.function): PMap.t D.t :=
+ match DS.fixpoint (successors f) f.(fn_nextpc) (transfer f)
+ ((f.(fn_entrypoint), D.top) :: nil) with
+ | None => PMap.init D.top
+ | Some res => res
+ end.
(** * Code transformation *)
@@ -986,6 +991,16 @@ End STRENGTH_REDUCTION.
and similarly for the addressing modes of load and store instructions.
Other instructions are unchanged. *)
+Definition transf_ros (approx: D.t) (ros: reg + ident) : reg + ident :=
+ match ros with
+ | inl r =>
+ match D.get r approx with
+ | S symb ofs => if Int.eq ofs Int.zero then inr _ symb else ros
+ | _ => ros
+ end
+ | inr s => ros
+ end.
+
Definition transf_instr (approx: D.t) (instr: instruction) :=
match instr with
| Iop op args res s =>
@@ -1007,16 +1022,9 @@ Definition transf_instr (approx: D.t) (instr: instruction) :=
let (addr', args') := addr_strength_reduction approx addr args in
Istore chunk addr' args' src s
| Icall sig ros args res s =>
- let ros' :=
- match ros with
- | inl r =>
- match D.get r approx with
- | S symb ofs => if Int.eq ofs Int.zero then inr _ symb else ros
- | _ => ros
- end
- | inr s => ros
- end in
- Icall sig ros' args res s
+ Icall sig (transf_ros approx ros) args res s
+ | Itailcall sig ros args =>
+ Itailcall sig (transf_ros approx ros) args
| Ialloc arg res s =>
Ialloc arg res s
| Icond cond args s1 s2 =>
@@ -1048,20 +1056,18 @@ Proof.
Qed.
Definition transf_function (f: function) : function :=
- match analyze f with
- | None => f
- | Some approxs =>
- mkfunction
- f.(fn_sig)
- f.(fn_params)
- f.(fn_stacksize)
- (transf_code approxs f.(fn_code))
- f.(fn_entrypoint)
- f.(fn_nextpc)
- (transf_code_wf f approxs f.(fn_code_wf))
- end.
+ let approxs := analyze f in
+ mkfunction
+ f.(fn_sig)
+ f.(fn_params)
+ f.(fn_stacksize)
+ (transf_code approxs f.(fn_code))
+ f.(fn_entrypoint)
+ f.(fn_nextpc)
+ (transf_code_wf f approxs f.(fn_code_wf)).
-Definition transf_fundef := AST.transf_fundef transf_function.
+Definition transf_fundef (fd: fundef) : fundef :=
+ AST.transf_fundef transf_function fd.
Definition transf_program (p: program) : program :=
transform_program transf_fundef p.
diff --git a/backend/Constpropproof.v b/backend/Constpropproof.v
index ee24187..dfa828b 100644
--- a/backend/Constpropproof.v
+++ b/backend/Constpropproof.v
@@ -9,6 +9,7 @@ Require Import Values.
Require Import Events.
Require Import Mem.
Require Import Globalenvs.
+Require Import Smallstep.
Require Import Op.
Require Import Registers.
Require Import RTL.
@@ -41,6 +42,13 @@ Definition val_match_approx (a: approx) (v: val) : Prop :=
Definition regs_match_approx (a: D.t) (rs: regset) : Prop :=
forall r, val_match_approx (D.get r a) rs#r.
+Lemma regs_match_approx_top:
+ forall rs, regs_match_approx D.top rs.
+Proof.
+ intros. red; intros. simpl. rewrite PTree.gempty.
+ unfold Approx.top, val_match_approx. auto.
+Qed.
+
Lemma val_match_approx_increasing:
forall a1 a2 v,
Approx.ge a1 a2 -> val_match_approx a2 v -> val_match_approx a1 v.
@@ -123,10 +131,10 @@ Ltac InvVLMA :=
approximations returned by [eval_static_operation]. *)
Lemma eval_static_condition_correct:
- forall cond al vl b,
+ forall cond al vl m b,
val_list_match_approx al vl ->
eval_static_condition cond al = Some b ->
- eval_condition cond vl = Some b.
+ eval_condition cond vl m = Some b.
Proof.
intros until b.
unfold eval_static_condition.
@@ -135,9 +143,9 @@ Proof.
Qed.
Lemma eval_static_operation_correct:
- forall op sp al vl v,
+ forall op sp al vl m v,
val_list_match_approx al vl ->
- eval_operation ge sp op vl = Some v ->
+ eval_operation ge sp op vl m = Some v ->
val_match_approx (eval_static_operation op al) v.
Proof.
intros until v.
@@ -183,7 +191,7 @@ Proof.
rewrite <- H3. replace v0 with (Vfloat n1). reflexivity. congruence.
caseEq (eval_static_condition c vl0).
- intros. generalize (eval_static_condition_correct _ _ _ _ H H1).
+ intros. generalize (eval_static_condition_correct _ _ _ m _ H H1).
intro. rewrite H2 in H0.
destruct b; injection H0; intro; subst v; simpl; auto.
intros; simpl; auto.
@@ -194,80 +202,40 @@ Proof.
auto.
Qed.
-(** The correctness of the transfer function follows: if the register
- state before a transition matches the static approximations at that
- program point, the register state after that transition matches
- the static approximation returned by the transfer function. *)
-
-Lemma transfer_correct:
- forall f c sp pc rs m t pc' rs' m' ra,
- exec_instr ge c sp pc rs m t pc' rs' m' ->
- c = f.(fn_code) ->
- regs_match_approx ra rs ->
- regs_match_approx (transfer f pc ra) rs'.
-Proof.
- induction 1; intros; subst c; unfold transfer; rewrite H; auto.
- (* Iop *)
- apply regs_match_approx_update.
- apply eval_static_operation_correct with sp rs##args.
- eapply approx_regs_val_list. auto. auto. auto.
- (* Iload *)
- apply regs_match_approx_update; auto. simpl; auto.
- (* Icall *)
- apply regs_match_approx_update; auto. simpl; auto.
- (* Ialloc *)
- apply regs_match_approx_update; auto. simpl; auto.
-Qed.
-
(** The correctness of the static analysis follows from the results
above and the fact that the result of the static analysis is
a solution of the forward dataflow inequations. *)
Lemma analyze_correct_1:
- forall f approxs,
- analyze f = Some approxs ->
- forall c sp pc rs m t pc' rs' m',
- exec_instr ge c sp pc rs m t pc' rs' m' ->
- c = f.(fn_code) ->
- regs_match_approx approxs!!pc rs ->
- regs_match_approx approxs!!pc' rs'.
+ forall f pc rs pc',
+ In pc' (successors f pc) ->
+ regs_match_approx (transfer f pc (analyze f)!!pc) rs ->
+ regs_match_approx (analyze f)!!pc' rs.
Proof.
- intros.
+ intros until pc'. unfold analyze.
+ caseEq (DS.fixpoint (successors f) (fn_nextpc f) (transfer f)
+ ((fn_entrypoint f, D.top) :: nil)).
+ intros approxs; intros.
apply regs_match_approx_increasing with (transfer f pc approxs!!pc).
- eapply DS.fixpoint_solution.
- unfold analyze in H. eexact H.
+ eapply DS.fixpoint_solution; eauto.
elim (fn_code_wf f pc); intro. auto.
- generalize (exec_instr_present _ _ _ _ _ _ _ _ _ _ H0).
- rewrite H1. intro. contradiction.
- eapply successors_correct. rewrite <- H1. eauto.
- eapply transfer_correct; eauto.
-Qed.
-
-Lemma analyze_correct_2:
- forall f approxs,
- analyze f = Some approxs ->
- forall c sp pc rs m t pc' rs' m',
- exec_instrs ge c sp pc rs m t pc' rs' m' ->
- c = f.(fn_code) ->
- regs_match_approx approxs!!pc rs ->
- regs_match_approx approxs!!pc' rs'.
-Proof.
- intros f approxs ANL. induction 1.
+ unfold successors in H0; rewrite H2 in H0; simpl; contradiction.
auto.
- intros. eapply analyze_correct_1; eauto.
- eauto.
+ intros. rewrite PMap.gi. apply regs_match_approx_top.
Qed.
Lemma analyze_correct_3:
- forall f approxs rs,
- analyze f = Some approxs ->
- regs_match_approx approxs!!(f.(fn_entrypoint)) rs.
+ forall f rs,
+ regs_match_approx (analyze f)!!(f.(fn_entrypoint)) rs.
Proof.
- intros.
+ intros. unfold analyze.
+ caseEq (DS.fixpoint (successors f) (fn_nextpc f) (transfer f)
+ ((fn_entrypoint f, D.top) :: nil)).
+ intros approxs; intros.
apply regs_match_approx_increasing with D.top.
- eapply DS.fixpoint_entry. unfold analyze in H; eexact H.
- auto with coqlib.
- red; intros. rewrite D.get_top. simpl; auto.
+ eapply DS.fixpoint_entry; eauto. auto with coqlib.
+ apply regs_match_approx_top.
+ intros. rewrite PMap.gi. apply regs_match_approx_top.
Qed.
(** * Correctness of strength reduction *)
@@ -296,9 +264,9 @@ Proof.
Qed.
Lemma cond_strength_reduction_correct:
- forall cond args,
+ forall cond args m,
let (cond', args') := cond_strength_reduction approx cond args in
- eval_condition cond' rs##args' = eval_condition cond rs##args.
+ eval_condition cond' rs##args' m = eval_condition cond rs##args m.
Proof.
intros. unfold cond_strength_reduction.
case (cond_strength_reduction_match cond args); intros.
@@ -312,7 +280,6 @@ Proof.
caseEq (intval approx r1); intros.
simpl. rewrite (intval_correct _ _ H).
destruct (rs#r2); auto. rewrite Int.swap_cmpu. auto.
- destruct c; reflexivity.
caseEq (intval approx r2); intros.
simpl. rewrite (intval_correct _ _ H0). auto.
auto.
@@ -320,10 +287,10 @@ Proof.
Qed.
Lemma make_addimm_correct:
- forall n r v,
+ forall n r m v,
let (op, args) := make_addimm n r in
- eval_operation ge sp Oadd (rs#r :: Vint n :: nil) = Some v ->
- eval_operation ge sp op rs##args = Some v.
+ eval_operation ge sp Oadd (rs#r :: Vint n :: nil) m = Some v ->
+ eval_operation ge sp op rs##args m = Some v.
Proof.
intros; unfold make_addimm.
generalize (Int.eq_spec n Int.zero); case (Int.eq n Int.zero); intros.
@@ -333,10 +300,10 @@ Proof.
Qed.
Lemma make_shlimm_correct:
- forall n r v,
+ forall n r m v,
let (op, args) := make_shlimm n r in
- eval_operation ge sp Oshl (rs#r :: Vint n :: nil) = Some v ->
- eval_operation ge sp op rs##args = Some v.
+ eval_operation ge sp Oshl (rs#r :: Vint n :: nil) m = Some v ->
+ eval_operation ge sp op rs##args m = Some v.
Proof.
intros; unfold make_shlimm.
generalize (Int.eq_spec n Int.zero); case (Int.eq n Int.zero); intros.
@@ -347,10 +314,10 @@ Proof.
Qed.
Lemma make_shrimm_correct:
- forall n r v,
+ forall n r m v,
let (op, args) := make_shrimm n r in
- eval_operation ge sp Oshr (rs#r :: Vint n :: nil) = Some v ->
- eval_operation ge sp op rs##args = Some v.
+ eval_operation ge sp Oshr (rs#r :: Vint n :: nil) m = Some v ->
+ eval_operation ge sp op rs##args m = Some v.
Proof.
intros; unfold make_shrimm.
generalize (Int.eq_spec n Int.zero); case (Int.eq n Int.zero); intros.
@@ -359,10 +326,10 @@ Proof.
Qed.
Lemma make_shruimm_correct:
- forall n r v,
+ forall n r m v,
let (op, args) := make_shruimm n r in
- eval_operation ge sp Oshru (rs#r :: Vint n :: nil) = Some v ->
- eval_operation ge sp op rs##args = Some v.
+ eval_operation ge sp Oshru (rs#r :: Vint n :: nil) m = Some v ->
+ eval_operation ge sp op rs##args m = Some v.
Proof.
intros; unfold make_shruimm.
generalize (Int.eq_spec n Int.zero); case (Int.eq n Int.zero); intros.
@@ -373,10 +340,10 @@ Proof.
Qed.
Lemma make_mulimm_correct:
- forall n r v,
+ forall n r m v,
let (op, args) := make_mulimm n r in
- eval_operation ge sp Omul (rs#r :: Vint n :: nil) = Some v ->
- eval_operation ge sp op rs##args = Some v.
+ eval_operation ge sp Omul (rs#r :: Vint n :: nil) m = Some v ->
+ eval_operation ge sp op rs##args m = Some v.
Proof.
intros; unfold make_mulimm.
generalize (Int.eq_spec n Int.zero); case (Int.eq n Int.zero); intros.
@@ -384,8 +351,8 @@ Proof.
generalize (Int.eq_spec n Int.one); case (Int.eq n Int.one); intros.
subst n. simpl in H1. simpl. FuncInv. rewrite Int.mul_one in H0. congruence.
caseEq (Int.is_power2 n); intros.
- replace (eval_operation ge sp Omul (rs # r :: Vint n :: nil))
- with (eval_operation ge sp Oshl (rs # r :: Vint i :: nil)).
+ replace (eval_operation ge sp Omul (rs # r :: Vint n :: nil) m)
+ with (eval_operation ge sp Oshl (rs # r :: Vint i :: nil) m).
apply make_shlimm_correct.
simpl. generalize (Int.is_power2_range _ _ H1).
change (Z_of_nat wordsize) with 32. intro. rewrite H2.
@@ -394,10 +361,10 @@ Proof.
Qed.
Lemma make_andimm_correct:
- forall n r v,
+ forall n r m v,
let (op, args) := make_andimm n r in
- eval_operation ge sp Oand (rs#r :: Vint n :: nil) = Some v ->
- eval_operation ge sp op rs##args = Some v.
+ eval_operation ge sp Oand (rs#r :: Vint n :: nil) m = Some v ->
+ eval_operation ge sp op rs##args m = Some v.
Proof.
intros; unfold make_andimm.
generalize (Int.eq_spec n Int.zero); case (Int.eq n Int.zero); intros.
@@ -408,10 +375,10 @@ Proof.
Qed.
Lemma make_orimm_correct:
- forall n r v,
+ forall n r m v,
let (op, args) := make_orimm n r in
- eval_operation ge sp Oor (rs#r :: Vint n :: nil) = Some v ->
- eval_operation ge sp op rs##args = Some v.
+ eval_operation ge sp Oor (rs#r :: Vint n :: nil) m = Some v ->
+ eval_operation ge sp op rs##args m = Some v.
Proof.
intros; unfold make_orimm.
generalize (Int.eq_spec n Int.zero); case (Int.eq n Int.zero); intros.
@@ -422,10 +389,10 @@ Proof.
Qed.
Lemma make_xorimm_correct:
- forall n r v,
+ forall n r m v,
let (op, args) := make_xorimm n r in
- eval_operation ge sp Oxor (rs#r :: Vint n :: nil) = Some v ->
- eval_operation ge sp op rs##args = Some v.
+ eval_operation ge sp Oxor (rs#r :: Vint n :: nil) m = Some v ->
+ eval_operation ge sp op rs##args m = Some v.
Proof.
intros; unfold make_xorimm.
generalize (Int.eq_spec n Int.zero); case (Int.eq n Int.zero); intros.
@@ -434,18 +401,18 @@ Proof.
Qed.
Lemma op_strength_reduction_correct:
- forall op args v,
+ forall op args m v,
let (op', args') := op_strength_reduction approx op args in
- eval_operation ge sp op rs##args = Some v ->
- eval_operation ge sp op' rs##args' = Some v.
+ eval_operation ge sp op rs##args m = Some v ->
+ eval_operation ge sp op' rs##args' m = Some v.
Proof.
intros; unfold op_strength_reduction;
case (op_strength_reduction_match op args); intros; simpl List.map.
(* Oadd *)
caseEq (intval approx r1); intros.
rewrite (intval_correct _ _ H).
- replace (eval_operation ge sp Oadd (Vint i :: rs # r2 :: nil))
- with (eval_operation ge sp Oadd (rs # r2 :: Vint i :: nil)).
+ replace (eval_operation ge sp Oadd (Vint i :: rs # r2 :: nil) m)
+ with (eval_operation ge sp Oadd (rs # r2 :: Vint i :: nil) m).
apply make_addimm_correct.
simpl. destruct rs#r2; auto. rewrite Int.add_commut; auto.
caseEq (intval approx r2); intros.
@@ -456,16 +423,16 @@ Proof.
rewrite (intval_correct _ _ H) in H0. assumption.
caseEq (intval approx r2); intros.
rewrite (intval_correct _ _ H0).
- replace (eval_operation ge sp Osub (rs # r1 :: Vint i :: nil))
- with (eval_operation ge sp Oadd (rs # r1 :: Vint (Int.neg i) :: nil)).
+ replace (eval_operation ge sp Osub (rs # r1 :: Vint i :: nil) m)
+ with (eval_operation ge sp Oadd (rs # r1 :: Vint (Int.neg i) :: nil) m).
apply make_addimm_correct.
simpl. destruct rs#r1; auto; rewrite Int.sub_add_opp; auto.
assumption.
(* Omul *)
caseEq (intval approx r1); intros.
rewrite (intval_correct _ _ H).
- replace (eval_operation ge sp Omul (Vint i :: rs # r2 :: nil))
- with (eval_operation ge sp Omul (rs # r2 :: Vint i :: nil)).
+ replace (eval_operation ge sp Omul (Vint i :: rs # r2 :: nil) m)
+ with (eval_operation ge sp Omul (rs # r2 :: Vint i :: nil) m).
apply make_mulimm_correct.
simpl. destruct rs#r2; auto. rewrite Int.mul_commut; auto.
caseEq (intval approx r2); intros.
@@ -485,8 +452,8 @@ Proof.
caseEq (intval approx r2); intros.
caseEq (Int.is_power2 i); intros.
rewrite (intval_correct _ _ H).
- replace (eval_operation ge sp Odivu (rs # r1 :: Vint i :: nil))
- with (eval_operation ge sp Oshru (rs # r1 :: Vint i0 :: nil)).
+ replace (eval_operation ge sp Odivu (rs # r1 :: Vint i :: nil) m)
+ with (eval_operation ge sp Oshru (rs # r1 :: Vint i0 :: nil) m).
apply make_shruimm_correct.
simpl. destruct rs#r1; auto.
change 32 with (Z_of_nat wordsize).
@@ -499,8 +466,8 @@ Proof.
(* Oand *)
caseEq (intval approx r1); intros.
rewrite (intval_correct _ _ H).
- replace (eval_operation ge sp Oand (Vint i :: rs # r2 :: nil))
- with (eval_operation ge sp Oand (rs # r2 :: Vint i :: nil)).
+ replace (eval_operation ge sp Oand (Vint i :: rs # r2 :: nil) m)
+ with (eval_operation ge sp Oand (rs # r2 :: Vint i :: nil) m).
apply make_andimm_correct.
simpl. destruct rs#r2; auto. rewrite Int.and_commut; auto.
caseEq (intval approx r2); intros.
@@ -509,8 +476,8 @@ Proof.
(* Oor *)
caseEq (intval approx r1); intros.
rewrite (intval_correct _ _ H).
- replace (eval_operation ge sp Oor (Vint i :: rs # r2 :: nil))
- with (eval_operation ge sp Oor (rs # r2 :: Vint i :: nil)).
+ replace (eval_operation ge sp Oor (Vint i :: rs # r2 :: nil) m)
+ with (eval_operation ge sp Oor (rs # r2 :: Vint i :: nil) m).
apply make_orimm_correct.
simpl. destruct rs#r2; auto. rewrite Int.or_commut; auto.
caseEq (intval approx r2); intros.
@@ -519,8 +486,8 @@ Proof.
(* Oxor *)
caseEq (intval approx r1); intros.
rewrite (intval_correct _ _ H).
- replace (eval_operation ge sp Oxor (Vint i :: rs # r2 :: nil))
- with (eval_operation ge sp Oxor (rs # r2 :: Vint i :: nil)).
+ replace (eval_operation ge sp Oxor (Vint i :: rs # r2 :: nil) m)
+ with (eval_operation ge sp Oxor (rs # r2 :: Vint i :: nil) m).
apply make_xorimm_correct.
simpl. destruct rs#r2; auto. rewrite Int.xor_commut; auto.
caseEq (intval approx r2); intros.
@@ -647,261 +614,329 @@ Let tge := Genv.globalenv tprog.
Lemma symbols_preserved:
forall (s: ident), Genv.find_symbol tge s = Genv.find_symbol ge s.
-Proof (Genv.find_symbol_transf transf_fundef prog).
+Proof.
+ intros; unfold ge, tge, tprog, transf_program.
+ apply Genv.find_symbol_transf.
+Qed.
Lemma functions_translated:
- forall (v: val) (f: RTL.fundef),
+ forall (v: val) (f: fundef),
Genv.find_funct ge v = Some f ->
Genv.find_funct tge v = Some (transf_fundef f).
-Proof (@Genv.find_funct_transf _ _ _ transf_fundef prog).
+Proof.
+ intros.
+ exact (Genv.find_funct_transf transf_fundef H).
+Qed.
Lemma function_ptr_translated:
- forall (v: block) (f: RTL.fundef),
- Genv.find_funct_ptr ge v = Some f ->
- Genv.find_funct_ptr tge v = Some (transf_fundef f).
-Proof (@Genv.find_funct_ptr_transf _ _ _ transf_fundef prog).
+ forall (b: block) (f: fundef),
+ Genv.find_funct_ptr ge b = Some f ->
+ Genv.find_funct_ptr tge b = Some (transf_fundef f).
+Proof.
+ intros.
+ exact (Genv.find_funct_ptr_transf transf_fundef H).
+Qed.
-Lemma sig_translated:
- forall (f: RTL.fundef),
+Lemma sig_function_translated:
+ forall f,
funsig (transf_fundef f) = funsig f.
Proof.
- intro. case f; intros; simpl.
- unfold transf_function. case (analyze f0); intros; reflexivity.
- reflexivity.
+ intros. destruct f; reflexivity.
+Qed.
+
+Lemma transf_ros_correct:
+ forall ros rs f approx,
+ regs_match_approx ge approx rs ->
+ find_function ge ros rs = Some f ->
+ find_function tge (transf_ros approx ros) rs = Some (transf_fundef f).
+Proof.
+ intros until approx; intro MATCH.
+ destruct ros; simpl.
+ intro.
+ exploit functions_translated; eauto. intro FIND.
+ caseEq (D.get r approx); intros; auto.
+ generalize (Int.eq_spec i0 Int.zero); case (Int.eq i0 Int.zero); intros; auto.
+ generalize (MATCH r). rewrite H0. intros [b [A B]].
+ rewrite <- symbols_preserved in A.
+ rewrite B in FIND. rewrite H1 in FIND.
+ rewrite Genv.find_funct_find_funct_ptr in FIND.
+ simpl. rewrite A. auto.
+ rewrite symbols_preserved. destruct (Genv.find_symbol ge i).
+ intro. apply function_ptr_translated. auto.
+ congruence.
Qed.
(** The proof of semantic preservation is a simulation argument
based on diagrams of the following form:
<<
- pc, rs, m ------------------- pc, rs, m
- | |
- | |
- v v
- pc', rs', m' ---------------- pc', rs', m'
+ st1 --------------- st2
+ | |
+ t| |t
+ | |
+ v v
+ st1'--------------- st2'
>>
The left vertical arrow represents a transition in the
- original RTL code. The top horizontal bar expresses that the values
- of registers [rs] match their compile-time approximations at point [pc].
+ original RTL code. The top horizontal bar is the [match_states]
+ invariant between the initial state [st1] in the original RTL code
+ and an initial state [st2] in the transformed code.
+ This invariant expresses that all code fragments appearing in [st2]
+ are obtained by [transf_code] transformation of the corresponding
+ fragments in [st1]. Moreover, the values of registers in [st1]
+ must match their compile-time approximations at the current program
+ point.
These two parts of the diagram are the hypotheses. In conclusions,
we want to prove the other two parts: the right vertical arrow,
which is a transition in the transformed RTL code, and the bottom
- horizontal bar, which means that [rs'] matches the compile-time
- approximations at [pc'].
-
- To help express those diagrams, we define the following propositions
- parameterized by the transition in the original RTL code (left arrow)
- and summarizing the three other arrows of the diagram. *)
-
-Definition exec_instr_prop
- (c: code) (sp: val)
- (pc: node) (rs: regset) (m: mem) (t: trace)
- (pc': node) (rs': regset) (m': mem) : Prop :=
- exec_instr tge c sp pc rs m t pc' rs' m' /\
- forall f approxs
- (CF: c = f.(RTL.fn_code))
- (ANL: analyze f = Some approxs)
- (MATCH: regs_match_approx ge approxs!!pc rs),
- exec_instr tge (transf_code approxs c) sp pc rs m t pc' rs' m'.
-
-Definition exec_instrs_prop
- (c: code) (sp: val)
- (pc: node) (rs: regset) (m: mem) (t: trace)
- (pc': node) (rs': regset) (m': mem) : Prop :=
- exec_instrs tge c sp pc rs m t pc' rs' m' /\
- forall f approxs
- (CF: c = f.(RTL.fn_code))
- (ANL: analyze f = Some approxs)
- (MATCH: regs_match_approx ge approxs!!pc rs),
- exec_instrs tge (transf_code approxs c) sp pc rs m t pc' rs' m'.
-
-Definition exec_function_prop
- (f: RTL.fundef) (args: list val) (m: mem) (t: trace)
- (res: val) (m': mem) : Prop :=
- exec_function tge (transf_fundef f) args m t res m'.
+ horizontal bar, which means that the [match_state] predicate holds
+ between the final states [st1'] and [st2']. *)
+
+Inductive match_stackframes: stackframe -> stackframe -> Prop :=
+ match_stackframe_intro:
+ forall res c sp pc rs f,
+ c = f.(RTL.fn_code) ->
+ (forall v, regs_match_approx ge (analyze f)!!pc (rs#res <- v)) ->
+ match_stackframes
+ (Stackframe res c sp pc rs)
+ (Stackframe res (transf_code (analyze f) c) sp pc rs).
+
+Inductive match_states: state -> state -> Prop :=
+ | match_states_intro:
+ forall s c sp pc rs m f s'
+ (CF: c = f.(RTL.fn_code))
+ (MATCH: regs_match_approx ge (analyze f)!!pc rs)
+ (STACKS: list_forall2 match_stackframes s s'),
+ match_states (State s c sp pc rs m)
+ (State s' (transf_code (analyze f) c) sp pc rs m)
+ | match_states_call:
+ forall s f args m s',
+ list_forall2 match_stackframes s s' ->
+ match_states (Callstate s f args m)
+ (Callstate s' (transf_fundef f) args m)
+ | match_states_return:
+ forall s s' v m,
+ list_forall2 match_stackframes s s' ->
+ match_states (Returnstate s v m)
+ (Returnstate s' v m).
Ltac TransfInstr :=
match goal with
- | H1: (PTree.get ?pc ?c = Some ?instr),
- H2: (analyze ?f = Some ?approxs) |- _ =>
- cut ((transf_code approxs c)!pc = Some(transf_instr approxs!!pc instr));
+ | H1: (PTree.get ?pc ?c = Some ?instr), f: function |- _ =>
+ cut ((transf_code (analyze f) c)!pc = Some(transf_instr (analyze f)!!pc instr));
[ simpl
| unfold transf_code; rewrite PTree.gmap;
unfold option_map; rewrite H1; reflexivity ]
end.
-(** The predicates above serve as induction hypotheses in the proof of
- simulation, which proceeds by induction over the
- evaluation derivation of the original code. *)
+(** The proof of simulation proceeds by case analysis on the transition
+ taken in the source code. *)
-Lemma transf_funct_correct:
- forall f args m t res m',
- exec_function ge f args m t res m' ->
- exec_function_prop f args m t res m'.
+Lemma transf_step_correct:
+ forall s1 t s2,
+ step ge s1 t s2 ->
+ forall s1' (MS: match_states s1 s1'),
+ exists s2', step tge s1' t s2' /\ match_states s2 s2'.
Proof.
- apply (exec_function_ind_3 ge
- exec_instr_prop exec_instrs_prop exec_function_prop);
- intros; red.
+ induction 1; intros; inv MS.
+
(* Inop *)
- split; [idtac| intros; TransfInstr].
- apply exec_Inop; auto.
- intros; apply exec_Inop; auto.
+ exists (State s' (transf_code (analyze f) (fn_code f)) sp pc' rs m); split.
+ TransfInstr; intro. eapply exec_Inop; eauto.
+ econstructor; eauto.
+ eapply analyze_correct_1 with (pc := pc); eauto.
+ unfold successors; rewrite H; auto with coqlib.
+ unfold transfer; rewrite H. auto.
+
(* Iop *)
- split; [idtac| intros; TransfInstr].
- apply exec_Iop with op args. auto.
- rewrite (eval_operation_preserved symbols_preserved). auto.
- caseEq (op_strength_reduction approxs!!pc op args);
+ exists (State s' (transf_code (analyze f) (fn_code f)) sp pc' (rs#res <- v) m); split.
+ TransfInstr. caseEq (op_strength_reduction (analyze f)!!pc op args);
intros op' args' OSR.
- assert (eval_operation tge sp op' rs##args' = Some v).
+ assert (eval_operation tge sp op' rs##args' m = Some v).
rewrite (eval_operation_preserved symbols_preserved).
- generalize (op_strength_reduction_correct ge approxs!!pc sp rs
- MATCH op args v).
+ generalize (op_strength_reduction_correct ge (analyze f)!!pc sp rs
+ MATCH op args m v).
rewrite OSR; simpl. auto.
generalize (eval_static_operation_correct ge op sp
- (approx_regs args approxs!!pc) rs##args v
+ (approx_regs args (analyze f)!!pc) rs##args m v
(approx_regs_val_list _ _ _ args MATCH) H0).
- case (eval_static_operation op (approx_regs args approxs!!pc)); intros;
- simpl in H1;
+ case (eval_static_operation op (approx_regs args (analyze f)!!pc)); intros;
+ simpl in H2;
eapply exec_Iop; eauto; simpl.
- simpl in H2; congruence.
- simpl in H2; congruence.
+ congruence.
+ congruence.
elim H2; intros b [A B]. rewrite symbols_preserved.
rewrite A; rewrite B; auto.
+ econstructor; eauto.
+ eapply analyze_correct_1 with (pc := pc); eauto.
+ unfold successors; rewrite H; auto with coqlib.
+ unfold transfer; rewrite H.
+ apply regs_match_approx_update; auto.
+ eapply eval_static_operation_correct; eauto.
+ apply approx_regs_val_list; auto.
+
(* Iload *)
- split; [idtac| intros; TransfInstr].
- eapply exec_Iload; eauto.
- rewrite (eval_addressing_preserved symbols_preserved). auto.
- caseEq (addr_strength_reduction approxs!!pc addr args);
+ caseEq (addr_strength_reduction (analyze f)!!pc addr args);
intros addr' args' ASR.
assert (eval_addressing tge sp addr' rs##args' = Some a).
rewrite (eval_addressing_preserved symbols_preserved).
- generalize (addr_strength_reduction_correct ge approxs!!pc sp rs
+ generalize (addr_strength_reduction_correct ge (analyze f)!!pc sp rs
MATCH addr args).
rewrite ASR; simpl. congruence.
- intro. eapply exec_Iload; eauto.
+ TransfInstr. rewrite ASR. intro.
+ exists (State s' (transf_code (analyze f) (fn_code f)) sp pc' (rs#dst <- v) m); split.
+ eapply exec_Iload; eauto.
+ econstructor; eauto.
+ apply analyze_correct_1 with pc; auto.
+ unfold successors; rewrite H; auto with coqlib.
+ unfold transfer; rewrite H.
+ apply regs_match_approx_update; auto. simpl; auto.
+
(* Istore *)
- split; [idtac| intros; TransfInstr].
- eapply exec_Istore; eauto.
- rewrite (eval_addressing_preserved symbols_preserved). auto.
- caseEq (addr_strength_reduction approxs!!pc addr args);
+ caseEq (addr_strength_reduction (analyze f)!!pc addr args);
intros addr' args' ASR.
assert (eval_addressing tge sp addr' rs##args' = Some a).
rewrite (eval_addressing_preserved symbols_preserved).
- generalize (addr_strength_reduction_correct ge approxs!!pc sp rs
+ generalize (addr_strength_reduction_correct ge (analyze f)!!pc sp rs
MATCH addr args).
- rewrite ASR; simpl. congruence.
- intro. eapply exec_Istore; eauto.
+ rewrite ASR; simpl. congruence.
+ TransfInstr. rewrite ASR. intro.
+ exists (State s' (transf_code (analyze f) (fn_code f)) sp pc' rs m'); split.
+ eapply exec_Istore; eauto.
+ econstructor; eauto.
+ apply analyze_correct_1 with pc; auto.
+ unfold successors; rewrite H; auto with coqlib.
+ unfold transfer; rewrite H. auto.
+
(* Icall *)
- assert (find_function tge ros rs = Some (transf_fundef f)).
- generalize H0; unfold find_function; destruct ros.
- apply functions_translated.
- rewrite symbols_preserved. destruct (Genv.find_symbol ge i).
- apply function_ptr_translated. congruence.
- assert (funsig (transf_fundef f) = sig).
- generalize (sig_translated f). congruence.
- split; [idtac| intros; TransfInstr].
- eapply exec_Icall; eauto.
- set (ros' :=
- match ros with
- | inl r =>
- match D.get r approxs !! pc with
- | Novalue => ros
- | Unknown => ros
- | I _ => ros
- | F _ => ros
- | S symb ofs => if Int.eq ofs Int.zero then inr reg symb else ros
- end
- | inr _ => ros
- end).
- intros; eapply exec_Icall; eauto.
- unfold ros'; destruct ros; auto.
- caseEq (D.get r approxs!!pc); intros; auto.
- generalize (Int.eq_spec i0 Int.zero); case (Int.eq i0 Int.zero); intros; auto.
- generalize (MATCH r). rewrite H7. intros [b [A B]].
- rewrite <- symbols_preserved in A.
- generalize H4. simpl. rewrite A. rewrite B. subst i0.
- rewrite Genv.find_funct_find_funct_ptr. auto.
+ exploit transf_ros_correct; eauto. intro FIND'.
+ TransfInstr; intro.
+ econstructor; split.
+ eapply exec_Icall; eauto. apply sig_function_translated; auto.
+ constructor; auto. constructor; auto.
+ econstructor; eauto.
+ intros. apply analyze_correct_1 with pc; auto.
+ unfold successors; rewrite H; auto with coqlib.
+ unfold transfer; rewrite H.
+ apply regs_match_approx_update; auto. simpl. auto.
+
+ (* Itailcall *)
+ exploit transf_ros_correct; eauto. intros FIND'.
+ TransfInstr; intro.
+ econstructor; split.
+ eapply exec_Itailcall; eauto. apply sig_function_translated; auto.
+ constructor; auto.
(* Ialloc *)
- split; [idtac|intros; TransfInstr].
- eapply exec_Ialloc; eauto.
- intros. eapply exec_Ialloc; eauto.
+ TransfInstr; intro.
+ exists (State s' (transf_code (analyze f) (fn_code f)) sp pc' (rs#res <- (Vptr b Int.zero)) m'); split.
+ eapply exec_Ialloc; eauto.
+ econstructor; eauto.
+ apply analyze_correct_1 with pc; auto.
+ unfold successors; rewrite H; auto with coqlib.
+ unfold transfer; rewrite H.
+ apply regs_match_approx_update; auto. simpl; auto.
(* Icond, true *)
- split; [idtac| intros; TransfInstr].
- eapply exec_Icond_true; eauto.
- caseEq (cond_strength_reduction approxs!!pc cond args);
+ exists (State s' (transf_code (analyze f) (fn_code f)) sp ifso rs m); split.
+ caseEq (cond_strength_reduction (analyze f)!!pc cond args);
intros cond' args' CSR.
- assert (eval_condition cond' rs##args' = Some true).
+ assert (eval_condition cond' rs##args' m = Some true).
generalize (cond_strength_reduction_correct
- ge approxs!!pc rs MATCH cond args).
+ ge (analyze f)!!pc rs MATCH cond args m).
rewrite CSR. intro. congruence.
- caseEq (eval_static_condition cond (approx_regs args approxs!!pc)).
+ TransfInstr. rewrite CSR.
+ caseEq (eval_static_condition cond (approx_regs args (analyze f)!!pc)).
intros b ESC.
- generalize (eval_static_condition_correct ge cond _ _ _
+ generalize (eval_static_condition_correct ge cond _ _ m _
(approx_regs_val_list _ _ _ args MATCH) ESC); intro.
replace b with true. intro; eapply exec_Inop; eauto. congruence.
- intros. eapply exec_Icond_true; eauto.
+ intros. eapply exec_Icond_true; eauto.
+ econstructor; eauto.
+ apply analyze_correct_1 with pc; auto.
+ unfold successors; rewrite H; auto with coqlib.
+ unfold transfer; rewrite H; auto.
(* Icond, false *)
- split; [idtac| intros; TransfInstr].
- eapply exec_Icond_false; eauto.
- caseEq (cond_strength_reduction approxs!!pc cond args);
+ exists (State s' (transf_code (analyze f) (fn_code f)) sp ifnot rs m); split.
+ caseEq (cond_strength_reduction (analyze f)!!pc cond args);
intros cond' args' CSR.
- assert (eval_condition cond' rs##args' = Some false).
+ assert (eval_condition cond' rs##args' m = Some false).
generalize (cond_strength_reduction_correct
- ge approxs!!pc rs MATCH cond args).
+ ge (analyze f)!!pc rs MATCH cond args m).
rewrite CSR. intro. congruence.
- caseEq (eval_static_condition cond (approx_regs args approxs!!pc)).
+ TransfInstr. rewrite CSR.
+ caseEq (eval_static_condition cond (approx_regs args (analyze f)!!pc)).
intros b ESC.
- generalize (eval_static_condition_correct ge cond _ _ _
+ generalize (eval_static_condition_correct ge cond _ _ m _
(approx_regs_val_list _ _ _ args MATCH) ESC); intro.
replace b with false. intro; eapply exec_Inop; eauto. congruence.
- intros. eapply exec_Icond_false; eauto.
-
- (* refl *)
- split. apply exec_refl. intros. apply exec_refl.
- (* one *)
- elim H0; intros.
- split. apply exec_one; auto.
- intros. apply exec_one. eapply H2; eauto.
- (* trans *)
- elim H0; intros. elim H2; intros.
- split.
- apply exec_trans with t1 pc2 rs2 m2 t2; auto.
- intros; apply exec_trans with t1 pc2 rs2 m2 t2.
- eapply H5; eauto. eapply H7; eauto.
- eapply analyze_correct_2; eauto. auto.
+ intros. eapply exec_Icond_false; eauto.
+ econstructor; eauto.
+ apply analyze_correct_1 with pc; auto.
+ unfold successors; rewrite H; auto with coqlib.
+ unfold transfer; rewrite H; auto.
+
+ (* Ireturn *)
+ exists (Returnstate s' (regmap_optget or Vundef rs) (free m stk)); split.
+ eapply exec_Ireturn; eauto. TransfInstr; auto.
+ constructor; auto.
(* internal function *)
- elim H1; intros.
- simpl. unfold transf_function.
- caseEq (analyze f).
- intros approxs ANL.
- eapply exec_funct_internal; simpl; eauto.
- eapply H5. reflexivity. auto.
+ simpl. unfold transf_function.
+ econstructor; split.
+ eapply exec_function_internal; simpl; eauto.
+ simpl. econstructor; eauto.
apply analyze_correct_3; auto.
- TransfInstr; auto.
- intros. eapply exec_funct_internal; eauto.
+
(* external function *)
- unfold transf_function; simpl. apply exec_funct_external; auto.
+ simpl. econstructor; split.
+ eapply exec_function_external; eauto.
+ constructor; auto.
+
+ (* return *)
+ inv H3. inv H1.
+ econstructor; split.
+ eapply exec_return; eauto.
+ econstructor; eauto.
+Qed.
+
+Lemma transf_initial_states:
+ forall st1, initial_state prog st1 ->
+ exists st2, initial_state tprog st2 /\ match_states st1 st2.
+Proof.
+ intros. inversion H.
+ exploit function_ptr_translated; eauto. intro FIND.
+ exists (Callstate nil (transf_fundef f) nil (Genv.init_mem tprog)); split.
+ econstructor; eauto.
+ replace (prog_main tprog) with (prog_main prog).
+ rewrite symbols_preserved. eauto.
+ reflexivity.
+ rewrite <- H2. apply sig_function_translated.
+ replace (Genv.init_mem tprog) with (Genv.init_mem prog).
+ constructor. constructor. auto.
+ symmetry. unfold tprog, transf_program. apply Genv.init_mem_transf.
+Qed.
+
+Lemma transf_final_states:
+ forall st1 st2 r,
+ match_states st1 st2 -> final_state st1 r -> final_state st2 r.
+Proof.
+ intros. inv H0. inv H. inv H4. constructor.
Qed.
(** The preservation of the observable behavior of the program then
- follows. *)
+ follows, using the generic preservation theorem
+ [Smallstep.simulation_step_preservation]. *)
Theorem transf_program_correct:
- forall (t: trace) (r: val),
- exec_program prog t r -> exec_program tprog t r.
+ forall (beh: program_behavior),
+ exec_program prog beh -> exec_program tprog beh.
Proof.
- intros t r [b [f [m [SYMB [FIND [SIG EXEC]]]]]].
- red. exists b. exists (transf_fundef f). exists m.
- split. change (prog_main tprog) with (prog_main prog).
- rewrite symbols_preserved. auto.
- split. apply function_ptr_translated; auto.
- split. generalize (sig_translated f). congruence.
- apply transf_funct_correct.
- unfold tprog, transf_program. rewrite Genv.init_mem_transf.
- exact EXEC.
+ unfold exec_program; intros.
+ eapply simulation_step_preservation; eauto.
+ eexact transf_initial_states.
+ eexact transf_final_states.
+ exact transf_step_correct.
Qed.
End PRESERVATION.
diff --git a/backend/Conventions.v b/backend/Conventions.v
index d621e7c..9d005b3 100644
--- a/backend/Conventions.v
+++ b/backend/Conventions.v
@@ -247,6 +247,31 @@ Proof.
apply temporaries_not_acceptable. auto.
Qed.
+Lemma loc_acceptable_noteq_diff:
+ forall l1 l2,
+ loc_acceptable l1 -> l1 <> l2 -> Loc.diff l1 l2.
+Proof.
+ unfold loc_acceptable, Loc.diff; destruct l1; destruct l2;
+ try (destruct s); try (destruct s0); intros; auto; try congruence.
+ case (zeq z z0); intro.
+ compare t t0; intro.
+ subst z0; subst t0; tauto.
+ tauto. tauto.
+ contradiction. contradiction.
+Qed.
+
+Lemma loc_acceptable_notin_notin:
+ forall r ll,
+ loc_acceptable r ->
+ ~(In r ll) -> Loc.notin r ll.
+Proof.
+ induction ll; simpl; intros.
+ auto.
+ split. apply loc_acceptable_noteq_diff. assumption.
+ apply sym_not_equal. tauto.
+ apply IHll. assumption. tauto.
+Qed.
+
(** * Function calling conventions *)
(** The functions in this section determine the locations (machine registers
@@ -292,9 +317,20 @@ Proof.
reflexivity.
Qed.
-(** The result location is a caller-save register. *)
+(** The result location is acceptable. *)
Lemma loc_result_acceptable:
+ forall sig, loc_acceptable (R (loc_result sig)).
+Proof.
+ intros. unfold loc_acceptable. red.
+ unfold loc_result. destruct (sig_res sig).
+ destruct t; simpl; NotOrEq.
+ simpl; NotOrEq.
+Qed.
+
+(** The result location is a caller-save register. *)
+
+Lemma loc_result_caller_save:
forall (s: signature), In (R (loc_result s)) destroyed_at_call.
Proof.
intros; unfold loc_result.
@@ -309,7 +345,7 @@ Lemma loc_result_not_callee_save:
forall (s: signature),
~(In (loc_result s) int_callee_save_regs \/ In (loc_result s) float_callee_save_regs).
Proof.
- intros. generalize (loc_result_acceptable s).
+ intros. generalize (loc_result_caller_save s).
generalize (int_callee_save_not_destroyed (loc_result s)).
generalize (float_callee_save_not_destroyed (loc_result s)).
tauto.
@@ -340,16 +376,18 @@ Fixpoint loc_arguments_rec
| nil => nil
| Tint :: tys =>
match iregl with
- | nil => S (Outgoing ofs Tint)
- | ireg :: _ => R ireg
- end ::
- loc_arguments_rec tys (list_drop1 iregl) fregl (ofs + 1)
+ | nil =>
+ S (Outgoing ofs Tint) :: loc_arguments_rec tys nil fregl (ofs + 1)
+ | ireg :: iregs =>
+ R ireg :: loc_arguments_rec tys iregs fregl ofs
+ end
| Tfloat :: tys =>
match fregl with
- | nil => S (Outgoing ofs Tfloat)
- | freg :: _ => R freg
- end ::
- loc_arguments_rec tys (list_drop2 iregl) (list_drop1 fregl) (ofs + 2)
+ | nil =>
+ S (Outgoing ofs Tfloat) :: loc_arguments_rec tys iregl nil (ofs + 2)
+ | freg :: fregs =>
+ R freg :: loc_arguments_rec tys (list_drop2 iregl) fregs ofs
+ end
end.
Definition int_param_regs :=
@@ -361,28 +399,45 @@ Definition float_param_regs :=
when calling a function with signature [s]. *)
Definition loc_arguments (s: signature) : list loc :=
- loc_arguments_rec s.(sig_args) int_param_regs float_param_regs 6.
+ loc_arguments_rec s.(sig_args) int_param_regs float_param_regs 14.
(** [size_arguments s] returns the number of [Outgoing] slots used
to call a function with signature [s]. *)
-Fixpoint size_arguments_rec (tyl: list typ) : Z :=
+Fixpoint size_arguments_rec
+ (tyl: list typ) (iregl: list mreg) (fregl: list mreg)
+ (ofs: Z) {struct tyl} : Z :=
match tyl with
- | nil => 6
- | Tint :: tys => 1 + size_arguments_rec tys
- | Tfloat :: tys => 2 + size_arguments_rec tys
+ | nil => ofs
+ | Tint :: tys =>
+ match iregl with
+ | nil => size_arguments_rec tys nil fregl (ofs + 1)
+ | ireg :: iregs => size_arguments_rec tys iregs fregl ofs
+ end
+ | Tfloat :: tys =>
+ match fregl with
+ | nil => size_arguments_rec tys iregl nil (ofs + 2)
+ | freg :: fregs => size_arguments_rec tys (list_drop2 iregl) fregs ofs
+ end
end.
Definition size_arguments (s: signature) : Z :=
- size_arguments_rec s.(sig_args).
+ size_arguments_rec s.(sig_args) int_param_regs float_param_regs 14.
+
+(** A tail-call is possible for a signature if the corresponding
+ arguments are all passed in registers. *)
+
+Definition tailcall_possible (s: signature) : Prop :=
+ forall l, In l (loc_arguments s) ->
+ match l with R _ => True | S _ => False end.
(** Argument locations are either non-temporary registers or [Outgoing]
- stack slots at offset 6 or more. *)
+ stack slots at offset 14 or more. *)
Definition loc_argument_acceptable (l: loc) : Prop :=
match l with
| R r => ~(In l temporaries)
- | S (Outgoing ofs ty) => ofs >= 6
+ | S (Outgoing ofs ty) => ofs >= 14
| _ => False
end.
@@ -397,16 +452,18 @@ Remark loc_arguments_rec_charact:
Proof.
induction tyl; simpl loc_arguments_rec; intros.
elim H.
- destruct a; elim H; intros.
- destruct iregl; subst l. omega. left; auto with coqlib.
- generalize (IHtyl _ _ _ _ H0).
- destruct l. intros [A|B]. left; apply list_drop1_incl; auto. tauto.
- destruct s; try contradiction. omega.
- destruct fregl; subst l. omega. right; auto with coqlib.
- generalize (IHtyl _ _ _ _ H0).
- destruct l. intros [A|B]. left; apply list_drop2_incl; auto.
- right; apply list_drop1_incl; auto.
- destruct s; try contradiction. omega.
+ destruct a.
+ destruct iregl; elim H; intro.
+ subst l. omega.
+ generalize (IHtyl _ _ _ _ H0). destruct l; auto. destruct s; auto. omega.
+ subst l. auto with coqlib.
+ generalize (IHtyl _ _ _ _ H0). destruct l; auto. simpl; intuition.
+ destruct fregl; elim H; intro.
+ subst l. omega.
+ generalize (IHtyl _ _ _ _ H0). destruct l; auto. destruct s; auto. omega.
+ subst l. auto with coqlib.
+ generalize (IHtyl _ _ _ _ H0). destruct l; auto.
+ intros [A|B]. left; apply list_drop2_incl; auto. right; auto with coqlib.
Qed.
Lemma loc_arguments_acceptable:
@@ -432,12 +489,15 @@ Remark loc_arguments_rec_notin_reg:
Proof.
induction tyl; simpl; intros.
auto.
- destruct a; simpl; split.
- destruct iregl. auto. red; intro; subst m. apply H. auto with coqlib.
- apply IHtyl. red; intro. apply H. apply list_drop1_incl; auto. auto.
- destruct fregl. auto. red; intro; subst m. apply H0. auto with coqlib.
- apply IHtyl. red; intro. apply H. apply list_drop2_incl; auto.
- red; intro. apply H0. apply list_drop1_incl; auto.
+ destruct a.
+ destruct iregl; simpl. auto.
+ simpl in H. split. apply sym_not_equal. tauto.
+ apply IHtyl. tauto. tauto.
+ destruct fregl; simpl. auto.
+ simpl in H0. split. apply sym_not_equal. tauto.
+ apply IHtyl.
+ red; intro. apply H. apply list_drop2_incl. auto.
+ tauto.
Qed.
Remark loc_arguments_rec_notin_local:
@@ -446,11 +506,9 @@ Remark loc_arguments_rec_notin_local:
Proof.
induction tyl; simpl; intros.
auto.
- destruct a; simpl; split.
- destruct iregl. auto. auto.
- apply IHtyl.
- destruct fregl. auto. auto.
- apply IHtyl.
+ destruct a.
+ destruct iregl; simpl; auto.
+ destruct fregl; simpl; auto.
Qed.
Remark loc_arguments_rec_notin_outgoing:
@@ -460,11 +518,13 @@ Remark loc_arguments_rec_notin_outgoing:
Proof.
induction tyl; simpl; intros.
auto.
- destruct a; simpl; split.
- destruct iregl. omega. auto.
- apply IHtyl. omega.
- destruct fregl. omega. auto.
- apply IHtyl. omega.
+ destruct a.
+ destruct iregl; simpl.
+ split. omega. eapply IHtyl. omega.
+ auto.
+ destruct fregl; simpl.
+ split. omega. eapply IHtyl. omega.
+ auto.
Qed.
Lemma loc_arguments_norepet:
@@ -477,21 +537,21 @@ Proof.
Loc.norepet (loc_arguments_rec tyl iregl fregl ofs)).
induction tyl; simpl; intros.
constructor.
- destruct a; constructor.
- destruct iregl.
- apply loc_arguments_rec_notin_outgoing. simpl; omega.
- apply loc_arguments_rec_notin_reg. simpl. inversion H. auto.
+ destruct a.
+ destruct iregl; constructor.
+ apply loc_arguments_rec_notin_outgoing. simpl; omega. auto.
+ apply loc_arguments_rec_notin_reg. inversion H. auto.
apply list_disjoint_notin with (m :: iregl); auto with coqlib.
- apply IHtyl. apply list_drop1_norepet; auto. auto.
- red; intros. apply H1. apply list_drop1_incl; auto. auto.
- destruct fregl.
- apply loc_arguments_rec_notin_outgoing. simpl; omega.
- apply loc_arguments_rec_notin_reg. simpl.
+ apply IHtyl. inv H; auto. auto.
+ eapply list_disjoint_cons_left; eauto.
+ destruct fregl; constructor.
+ apply loc_arguments_rec_notin_outgoing. simpl; omega. auto.
+ apply loc_arguments_rec_notin_reg.
red; intro. apply (H1 m m). apply list_drop2_incl; auto.
- auto with coqlib. auto.
- simpl. inversion H0. auto.
- apply IHtyl. apply list_drop2_norepet; auto. apply list_drop1_norepet; auto.
- red; intros. apply H1. apply list_drop2_incl; auto. apply list_drop1_incl; auto.
+ auto with coqlib. auto. inv H0; auto.
+ apply IHtyl. apply list_drop2_norepet; auto.
+ inv H0; auto.
+ red; intros. apply H1. apply list_drop2_incl; auto. auto with coqlib.
intro. unfold loc_arguments. apply H.
unfold int_param_regs. NoRepet.
@@ -501,32 +561,42 @@ Qed.
(** The offsets of [Outgoing] arguments are below [size_arguments s]. *)
+Remark size_arguments_rec_above:
+ forall tyl iregl fregl ofs0,
+ ofs0 <= size_arguments_rec tyl iregl fregl ofs0.
+Proof.
+ induction tyl; simpl; intros.
+ omega.
+ destruct a.
+ destruct iregl. apply Zle_trans with (ofs0 + 1); auto; omega. auto.
+ destruct fregl. apply Zle_trans with (ofs0 + 2); auto; omega. auto.
+Qed.
+
+Lemma size_arguments_above:
+ forall s, size_arguments s >= 14.
+Proof.
+ intros; unfold size_arguments. apply Zle_ge.
+ apply size_arguments_rec_above.
+Qed.
+
Lemma loc_arguments_bounded:
forall (s: signature) (ofs: Z) (ty: typ),
In (S (Outgoing ofs ty)) (loc_arguments s) ->
ofs + typesize ty <= size_arguments s.
Proof.
intros.
- assert (forall tyl, size_arguments_rec tyl >= 6).
- induction tyl; unfold size_arguments_rec; fold size_arguments_rec; intros.
- omega.
- destruct a; omega.
assert (forall tyl iregl fregl ofs0,
In (S (Outgoing ofs ty)) (loc_arguments_rec tyl iregl fregl ofs0) ->
- ofs + typesize ty <= size_arguments_rec tyl + ofs0 - 6).
- induction tyl; simpl loc_arguments_rec; intros.
- elim H1.
- unfold size_arguments_rec; fold size_arguments_rec.
- destruct a.
- elim H1; intro. destruct iregl; simplify_eq H2; intros.
- subst ty; subst ofs. generalize (H0 tyl). simpl typesize. omega.
- generalize (IHtyl _ _ _ H2). omega.
- elim H1; intro. destruct fregl; simplify_eq H2; intros.
- subst ty; subst ofs. generalize (H0 tyl). simpl typesize. omega.
- generalize (IHtyl _ _ _ H2). omega.
- replace (size_arguments s) with (size_arguments s + 6 - 6).
- unfold size_arguments. eapply H1. unfold loc_arguments in H. eauto.
- omega.
+ ofs + typesize ty <= size_arguments_rec tyl iregl fregl ofs0).
+ induction tyl; simpl; intros.
+ elim H0.
+ destruct a. destruct iregl; elim H0; intro.
+ inv H1. simpl. apply size_arguments_rec_above. auto.
+ discriminate. auto.
+ destruct fregl; elim H0; intro.
+ inv H1. simpl. apply size_arguments_rec_above. auto.
+ discriminate. auto.
+ unfold size_arguments. eapply H0. unfold loc_arguments in H. eauto.
Qed.
(** Temporary registers do not overlap with argument locations. *)
@@ -543,6 +613,18 @@ Proof.
Qed.
Hint Resolve loc_arguments_not_temporaries: locs.
+(** Argument registers are caller-save. *)
+
+Lemma arguments_caller_save:
+ forall sig r,
+ In (R r) (loc_arguments sig) -> In (R r) destroyed_at_call.
+Proof.
+ unfold loc_arguments; intros.
+ elim (loc_arguments_rec_charact _ _ _ _ _ H); simpl.
+ ElimOrEq; intuition.
+ ElimOrEq; intuition.
+Qed.
+
(** Callee-save registers do not overlap with argument locations. *)
Lemma arguments_not_preserved:
@@ -571,7 +653,9 @@ Proof.
List.length (loc_arguments_rec tyl iregl fregl ofs) = List.length tyl).
induction tyl; simpl; intros.
auto.
- destruct a; simpl; decEq; auto.
+ destruct a.
+ destruct iregl; simpl; decEq; auto.
+ destruct fregl; simpl; decEq; auto.
intros. unfold loc_arguments. auto.
Qed.
@@ -586,14 +670,10 @@ Proof.
List.map Loc.type (loc_arguments_rec tyl iregl fregl ofs) = tyl).
induction tyl; simpl; intros.
auto.
- destruct a; simpl; apply (f_equal2 (@cons typ)).
- destruct iregl. reflexivity. simpl. apply H. auto with coqlib.
- apply IHtyl.
- intros. apply H. apply list_drop1_incl. auto. auto.
- destruct fregl. reflexivity. simpl. apply H0. auto with coqlib.
- apply IHtyl.
- intros. apply H. apply list_drop2_incl. auto.
- intros. apply H0. apply list_drop1_incl. auto.
+ destruct a; [destruct iregl|destruct fregl]; simpl;
+ f_equal; eauto with coqlib.
+ apply IHtyl. intros. apply H. apply list_drop2_incl; auto.
+ eauto with coqlib.
intros. unfold loc_arguments. apply H.
intro; simpl. ElimOrEq; reflexivity.
@@ -618,6 +698,30 @@ Proof.
destruct s; try tauto. destruct s0; tauto.
Qed.
+(** A tailcall is possible if and only if the size of arguments is 14. *)
+
+Lemma tailcall_possible_size:
+ forall s, tailcall_possible s <-> size_arguments s = 14.
+Proof.
+ intro; split; intro.
+ assert (forall tyl iregl fregl ofs,
+ (forall l, In l (loc_arguments_rec tyl iregl fregl ofs) ->
+ match l with R _ => True | S _ => False end) ->
+ size_arguments_rec tyl iregl fregl ofs = ofs).
+ induction tyl; simpl; intros.
+ auto.
+ destruct a. destruct iregl. elim (H0 _ (in_eq _ _)).
+ apply IHtyl; intros. apply H0. auto with coqlib.
+ destruct fregl. elim (H0 _ (in_eq _ _)).
+ apply IHtyl; intros. apply H0. auto with coqlib.
+ unfold size_arguments. apply H0. assumption.
+ red; intros.
+ generalize (loc_arguments_acceptable s l H0).
+ destruct l; simpl. auto. destruct s0; intro; auto.
+ generalize (loc_arguments_bounded _ _ _ H0).
+ generalize (typesize_pos t). omega.
+Qed.
+
(** ** Location of function parameters *)
(** A function finds the values of its parameter in the same locations
@@ -645,6 +749,13 @@ Proof.
destruct s; reflexivity.
Qed.
+Lemma loc_parameters_length:
+ forall sg, List.length (loc_parameters sg) = List.length sg.(sig_args).
+Proof.
+ intros. unfold loc_parameters. rewrite list_length_map.
+ apply loc_arguments_length.
+Qed.
+
Lemma loc_parameters_not_temporaries:
forall sig, Loc.disjoint (loc_parameters sig) temporaries.
Proof.
@@ -676,7 +787,7 @@ Proof.
intros; simpl. tauto.
Qed.
-(** ** Location of argument and result of dynamic allocation *)
+(** ** Location of argument and result for dynamic memory allocation *)
Definition loc_alloc_argument := R3.
Definition loc_alloc_result := R3.
diff --git a/backend/LTL.v b/backend/LTL.v
index 0dc9702..edb8ecc 100644
--- a/backend/LTL.v
+++ b/backend/LTL.v
@@ -3,7 +3,6 @@
LTL (``Location Transfer Language'') is the target language
for register allocation and the source language for linearization. *)
-Require Import Relations.
Require Import Coqlib.
Require Import Maps.
Require Import AST.
@@ -12,54 +11,38 @@ Require Import Values.
Require Import Events.
Require Import Mem.
Require Import Globalenvs.
+Require Import Smallstep.
Require Import Op.
Require Import Locations.
-Require Conventions.
+Require Import Conventions.
(** * Abstract syntax *)
-(** LTL is close to RTL, but uses locations instead of pseudo-registers,
- and basic blocks instead of single instructions as nodes of its
- control-flow graph. *)
+(** LTL is close to RTL, but uses locations instead of pseudo-registers. *)
Definition node := positive.
-(** A basic block is a sequence of instructions terminated by
- a [Bgoto], [Bcond] or [Breturn] instruction. (This invariant
- is enforced by the following inductive type definition.)
- The instructions behave like the similarly-named instructions
- of RTL. They take machine registers (type [mreg]) as arguments
- and results. Two new instructions are added: [Bgetstack]
- and [Bsetstack], which are ``move'' instructions between
- a machine register and a stack slot. *)
-
-Inductive block: Set :=
- | Bgetstack: slot -> mreg -> block -> block
- | Bsetstack: mreg -> slot -> block -> block
- | Bop: operation -> list mreg -> mreg -> block -> block
- | Bload: memory_chunk -> addressing -> list mreg -> mreg -> block -> block
- | Bstore: memory_chunk -> addressing -> list mreg -> mreg -> block -> block
- | Bcall: signature -> mreg + ident -> block -> block
- | Balloc: block -> block
- | Bgoto: node -> block
- | Bcond: condition -> list mreg -> node -> node -> block
- | Breturn: block.
-
-Definition code: Set := PTree.t block.
-
-(** Unlike in RTL, parameter passing (passing values of the arguments
- to a function call to the parameters of the called function) is done
- via conventional locations (machine registers and stack slots).
- Consequently, the [Bcall] instruction has no list of argument registers,
- and function descriptions have no list of parameter registers. *)
+Inductive instruction: Set :=
+ | Lnop: node -> instruction
+ | Lop: operation -> list loc -> loc -> node -> instruction
+ | Lload: memory_chunk -> addressing -> list loc -> loc -> node -> instruction
+ | Lstore: memory_chunk -> addressing -> list loc -> loc -> node -> instruction
+ | Lcall: signature -> loc + ident -> list loc -> loc -> node -> instruction
+ | Ltailcall: signature -> loc + ident -> list loc -> instruction
+ | Lalloc: loc -> loc -> node -> instruction
+ | Lcond: condition -> list loc -> node -> node -> instruction
+ | Lreturn: option loc -> instruction.
+
+Definition code: Set := PTree.t instruction.
Record function: Set := mkfunction {
fn_sig: signature;
+ fn_params: list loc;
fn_stacksize: Z;
fn_code: code;
fn_entrypoint: node;
- fn_code_wf:
- forall (pc: node), Plt pc (Psucc fn_entrypoint) \/ fn_code!pc = None
+ fn_nextpc: node;
+ fn_code_wf: forall (pc: node), Plt pc fn_nextpc \/ fn_code!pc = None
}.
Definition fundef := AST.fundef function.
@@ -107,7 +90,7 @@ Definition call_regs (caller: locset) : locset :=
set [callee] of the callee at the return instruction.
- Callee-save machine registers have the same values as in the caller
before the call.
-- Caller-save and temporary machine registers have the same values
+- Caller-save machine registers have the same values
as in the callee at the return point.
- Stack slots have the same values as in the caller before the call.
*)
@@ -125,11 +108,72 @@ Definition return_regs (caller callee: locset) : locset :=
| S s => caller (S s)
end.
+(** [parmov srcs dsts ls] performs the parallel assignment
+ of locations [dsts] to the values of the corresponding locations
+ [srcs]. *)
+
+Fixpoint parmov (srcs dsts: list loc) (ls: locset) {struct srcs} : locset :=
+ match srcs, dsts with
+ | s1 :: sl, d1 :: dl => Locmap.set d1 (ls s1) (parmov sl dl ls)
+ | _, _ => ls
+ end.
+
+Definition set_result_reg (s: signature) (or: option loc) (ls: locset) :=
+ match or with
+ | Some r => Locmap.set (R (loc_result s)) (ls r) ls
+ | None => ls
+ end.
+
+(** The components of an LTL execution state are:
+
+- [State cs f sp pc ls m]: [f] is the function currently executing.
+ [sp] is the stack pointer (as in RTL). [pc] is the current
+ program point (CFG node) within the code of [f].
+ [ls] maps locations to their current values. [m] is the current
+ memory state.
+- [Callstate cs f ls m]:
+ [f] is the function definition that we are calling.
+ [ls] is the values of locations just before the call.
+ [m] is the current memory state.
+- [Returnstate cs sig ls m]:
+ [sig] is the signature of the function that just returned.
+ [ls] is the values of locations just before the return.
+ [m] is the current memory state.
+
+[cs] is a list of stack frames [Stackframe res f sp ls pc],
+where [res] is the location that will receive the result of the call,
+[f] is the calling function, [sp] its stack pointer,
+[ls] the values of locations just before the call,
+and [pc] the program point within [f] of the successor of the
+[Lcall] instruction. *)
+
+Inductive stackframe : Set :=
+ | Stackframe:
+ forall (res: loc) (f: function) (sp: val) (ls: locset) (pc: node),
+ stackframe.
+
+Inductive state : Set :=
+ | State:
+ forall (stack: list stackframe) (f: function) (sp: val)
+ (pc: node) (ls: locset) (m: mem), state
+ | Callstate:
+ forall (stack: list stackframe) (f: fundef) (ls: locset) (m: mem),
+ state
+ | Returnstate:
+ forall (stack: list stackframe) (sig: signature) (ls: locset) (m: mem),
+ state.
+
+Definition parent_locset (stack: list stackframe) : locset :=
+ match stack with
+ | nil => Locmap.init Vundef
+ | Stackframe res f sp ls pc :: stack' => ls
+ end.
+
Variable ge: genv.
-Definition find_function (ros: mreg + ident) (rs: locset) : option fundef :=
- match ros with
- | inl r => Genv.find_funct ge (rs (R r))
+Definition find_function (los: loc + ident) (rs: locset) : option fundef :=
+ match los with
+ | inl l => Genv.find_funct ge (rs l)
| inr symb =>
match Genv.find_symbol ge symb with
| None => None
@@ -137,158 +181,140 @@ Definition find_function (ros: mreg + ident) (rs: locset) : option fundef :=
end
end.
-Definition reglist (rl: list mreg) (rs: locset) : list val :=
- List.map (fun r => rs (R r)) rl.
-
-(** The dynamic semantics of LTL, like that of RTL, is a combination
- of small-step transition semantics and big-step semantics.
- Function calls are treated in big-step style so that they appear
- as a single transition in the caller function. Other instructions
- are treated in purely small-step style, as a single transition.
-
- The introduction of basic blocks increases the number of inductive
- predicates needed to express the semantics:
-- [exec_instr ge sp b ls m b' ls' m'] is the execution of the first
- instruction of block [b]. [b'] is the remainder of the block.
-- [exec_instrs ge sp b ls m b' ls' m'] is similar, but executes
- zero, one or several instructions at the beginning of block [b].
-- [exec_block ge sp b ls m out ls' m'] executes all instructions
- of block [b]. The outcome [out] is either [Cont s], indicating
- that the block terminates by branching to block labeled [s],
- or [Return], indicating that the block terminates by returning
- from the current function.
-- [exec_blocks ge code sp pc ls m out ls' m'] executes a sequence
- of zero, one or several blocks, starting at the block labeled [pc].
- [code] is the control-flow graph for the current function.
- The outcome [out] indicates how the last block in this sequence
- terminates: by branching to another block or by returning from the
- function.
-- [exec_function ge f ls m ls' m'] executes the body of function [f],
- from its entry point to the first [Lreturn] instruction encountered.
-
- In all these predicates, [ls] and [ls'] are the location sets
- (values of locations) at the beginning and end of the transitions,
- respectively.
+(** The main difference between the LTL transition relation
+ and the RTL transition relation is the handling of function calls.
+ In RTL, arguments and results to calls are transmitted via
+ [vargs] and [vres] components of [Callstate] and [Returnstate],
+ respectively. The semantics takes care of transferring these values
+ between the pseudo-registers of the caller and of the callee.
+
+ In lower-level intermediate languages (e.g [Linear], [Mach], [PPC]),
+ arguments and results are transmitted implicitly: the generated
+ code for the caller arranges for arguments to be left in conventional
+ registers and stack locations, as determined by the calling conventions,
+ where the function being called will find them. Similarly,
+ conventional registers will be used to pass the result value back
+ to the caller.
+
+ In LTL, we take an hybrid view of argument and result passing.
+ The LTL code does not contain (yet) instructions for moving
+ arguments and results to the conventional registers. However,
+ the dynamic semantics "goes through the motions" of such code:
+- The [exec_Lcall] transition from [State] to [Callstate]
+ leaves the values of arguments in the conventional locations
+ given by [loc_arguments].
+- The [exec_function_internal] transition from [Callstate] to [State]
+ changes the view of stack slots ([Outgoing] slots slide to
+ [Incoming] slots as per [call_regs]), then recovers the
+ values of parameters from the conventional locations given by
+ [loc_parameters].
+- The [exec_Lreturn] transition from [State] to [Returnstate]
+ moves the result value to the conventional location [loc_result],
+ then restores the values of callee-save locations from
+ the location state of the caller, using [return_regs].
+- The [exec_return] transition from [Returnstate] to [State]
+ reads the result value from the conventional location [loc_result],
+ then stores it in the result location for the [Lcall] instruction.
+
+This complicated protocol will make it much easier to prove
+the correctness of the [Stacking] pass later, which inserts actual
+code that performs all the shuffling of arguments and results
+described above.
*)
-Inductive outcome: Set :=
- | Cont: node -> outcome
- | Return: outcome.
-
-Inductive exec_instr: val ->
- block -> locset -> mem -> trace ->
- block -> locset -> mem -> Prop :=
- | exec_Bgetstack:
- forall sp sl r b rs m,
- exec_instr sp (Bgetstack sl r b) rs m
- E0 b (Locmap.set (R r) (rs (S sl)) rs) m
- | exec_Bsetstack:
- forall sp r sl b rs m,
- exec_instr sp (Bsetstack r sl b) rs m
- E0 b (Locmap.set (S sl) (rs (R r)) rs) m
- | exec_Bop:
- forall sp op args res b rs m v,
- eval_operation ge sp op (reglist args rs) = Some v ->
- exec_instr sp (Bop op args res b) rs m
- E0 b (Locmap.set (R res) v rs) m
- | exec_Bload:
- forall sp chunk addr args dst b rs m a v,
- eval_addressing ge sp addr (reglist args rs) = Some a ->
- loadv chunk m a = Some v ->
- exec_instr sp (Bload chunk addr args dst b) rs m
- E0 b (Locmap.set (R dst) v rs) m
- | exec_Bstore:
- forall sp chunk addr args src b rs m m' a,
- eval_addressing ge sp addr (reglist args rs) = Some a ->
- storev chunk m a (rs (R src)) = Some m' ->
- exec_instr sp (Bstore chunk addr args src b) rs m
- E0 b rs m'
- | exec_Bcall:
- forall sp sig ros b rs m t f rs' m',
- find_function ros rs = Some f ->
- sig = funsig f ->
- exec_function f rs m t rs' m' ->
- exec_instr sp (Bcall sig ros b) rs m
- t b (return_regs rs rs') m'
- | exec_Balloc:
- forall sp b rs m sz m' blk,
- rs (R Conventions.loc_alloc_argument) = Vint sz ->
- Mem.alloc m 0 (Int.signed sz) = (m', blk) ->
- exec_instr sp (Balloc b) rs m E0 b
- (Locmap.set (R Conventions.loc_alloc_result)
- (Vptr blk Int.zero) rs) m'
-
-with exec_instrs: val ->
- block -> locset -> mem -> trace ->
- block -> locset -> mem -> Prop :=
- | exec_refl:
- forall sp b rs m,
- exec_instrs sp b rs m E0 b rs m
- | exec_one:
- forall sp b1 rs1 m1 t b2 rs2 m2,
- exec_instr sp b1 rs1 m1 t b2 rs2 m2 ->
- exec_instrs sp b1 rs1 m1 t b2 rs2 m2
- | exec_trans:
- forall sp b1 rs1 m1 t t1 b2 rs2 m2 t2 b3 rs3 m3,
- exec_instrs sp b1 rs1 m1 t1 b2 rs2 m2 ->
- exec_instrs sp b2 rs2 m2 t2 b3 rs3 m3 ->
- t = t1 ** t2 ->
- exec_instrs sp b1 rs1 m1 t b3 rs3 m3
-
-with exec_block: val ->
- block -> locset -> mem -> trace ->
- outcome -> locset -> mem -> Prop :=
- | exec_Bgoto:
- forall sp b rs m t s rs' m',
- exec_instrs sp b rs m t (Bgoto s) rs' m' ->
- exec_block sp b rs m t (Cont s) rs' m'
- | exec_Bcond_true:
- forall sp b rs m t cond args ifso ifnot rs' m',
- exec_instrs sp b rs m t (Bcond cond args ifso ifnot) rs' m' ->
- eval_condition cond (reglist args rs') = Some true ->
- exec_block sp b rs m t (Cont ifso) rs' m'
- | exec_Bcond_false:
- forall sp b rs m t cond args ifso ifnot rs' m',
- exec_instrs sp b rs m t (Bcond cond args ifso ifnot) rs' m' ->
- eval_condition cond (reglist args rs') = Some false ->
- exec_block sp b rs m t (Cont ifnot) rs' m'
- | exec_Breturn:
- forall sp b rs m t rs' m',
- exec_instrs sp b rs m t Breturn rs' m' ->
- exec_block sp b rs m t Return rs' m'
-
-with exec_blocks: code -> val ->
- node -> locset -> mem -> trace ->
- outcome -> locset -> mem -> Prop :=
- | exec_blocks_refl:
- forall c sp pc rs m,
- exec_blocks c sp pc rs m E0 (Cont pc) rs m
- | exec_blocks_one:
- forall c sp pc b m rs t out rs' m',
- c!pc = Some b ->
- exec_block sp b rs m t out rs' m' ->
- exec_blocks c sp pc rs m t out rs' m'
- | exec_blocks_trans:
- forall c sp pc1 rs1 m1 t t1 pc2 rs2 m2 t2 out rs3 m3,
- exec_blocks c sp pc1 rs1 m1 t1 (Cont pc2) rs2 m2 ->
- exec_blocks c sp pc2 rs2 m2 t2 out rs3 m3 ->
- t = t1 ** t2 ->
- exec_blocks c sp pc1 rs1 m1 t out rs3 m3
-
-with exec_function: fundef -> locset -> mem -> trace ->
- locset -> mem -> Prop :=
- | exec_funct_internal:
- forall f rs m m1 stk t rs2 m2,
- alloc m 0 f.(fn_stacksize) = (m1, stk) ->
- exec_blocks f.(fn_code) (Vptr stk Int.zero)
- f.(fn_entrypoint) (call_regs rs) m1 t Return rs2 m2 ->
- exec_function (Internal f) rs m t rs2 (free m2 stk)
- | exec_funct_external:
- forall ef args res rs1 rs2 m t,
+Inductive step: state -> trace -> state -> Prop :=
+ | exec_Lnop:
+ forall s f sp pc rs m pc',
+ (fn_code f)!pc = Some(Lnop pc') ->
+ step (State s f sp pc rs m)
+ E0 (State s f sp pc' rs m)
+ | exec_Lop:
+ forall s f sp pc rs m op args res pc' v,
+ (fn_code f)!pc = Some(Lop op args res pc') ->
+ eval_operation ge sp op (map rs args) m = Some v ->
+ step (State s f sp pc rs m)
+ E0 (State s f sp pc' (Locmap.set res v rs) m)
+ | exec_Lload:
+ forall s f sp pc rs m chunk addr args dst pc' a v,
+ (fn_code f)!pc = Some(Lload chunk addr args dst pc') ->
+ eval_addressing ge sp addr (map rs args) = Some a ->
+ Mem.loadv chunk m a = Some v ->
+ step (State s f sp pc rs m)
+ E0 (State s f sp pc' (Locmap.set dst v rs) m)
+ | exec_Lstore:
+ forall s f sp pc rs m chunk addr args src pc' a m',
+ (fn_code f)!pc = Some(Lstore chunk addr args src pc') ->
+ eval_addressing ge sp addr (map rs args) = Some a ->
+ Mem.storev chunk m a (rs src) = Some m' ->
+ step (State s f sp pc rs m)
+ E0 (State s f sp pc' rs m')
+ | exec_Lcall:
+ forall s f sp pc rs m sig ros args res pc' f',
+ (fn_code f)!pc = Some(Lcall sig ros args res pc') ->
+ find_function ros rs = Some f' ->
+ funsig f' = sig ->
+ let rs1 := parmov args (loc_arguments sig) rs in
+ step (State s f sp pc rs m)
+ E0 (Callstate (Stackframe res f sp rs1 pc' :: s) f' rs1 m)
+ | exec_Ltailcall:
+ forall s f stk pc rs m sig ros args f',
+ (fn_code f)!pc = Some(Ltailcall sig ros args) ->
+ find_function ros rs = Some f' ->
+ funsig f' = sig ->
+ let rs1 := parmov args (loc_arguments sig) rs in
+ let rs2 := return_regs (parent_locset s) rs1 in
+ step (State s f (Vptr stk Int.zero) pc rs m)
+ E0 (Callstate s f' rs2 (Mem.free m stk))
+ | exec_Lalloc:
+ forall s f sp pc rs m pc' arg res sz m' b,
+ (fn_code f)!pc = Some(Lalloc arg res pc') ->
+ rs arg = Vint sz ->
+ Mem.alloc m 0 (Int.signed sz) = (m', b) ->
+ let rs1 := Locmap.set (R loc_alloc_argument) (rs arg) rs in
+ let rs2 := Locmap.set (R loc_alloc_result) (Vptr b Int.zero) rs1 in
+ let rs3 := Locmap.set res (rs2 (R loc_alloc_result)) rs2 in
+ step (State s f sp pc rs m)
+ E0 (State s f sp pc' rs3 m')
+ | exec_Lcond_true:
+ forall s f sp pc rs m cond args ifso ifnot,
+ (fn_code f)!pc = Some(Lcond cond args ifso ifnot) ->
+ eval_condition cond (map rs args) m = Some true ->
+ step (State s f sp pc rs m)
+ E0 (State s f sp ifso rs m)
+ | exec_Lcond_false:
+ forall s f sp pc rs m cond args ifso ifnot,
+ (fn_code f)!pc = Some(Lcond cond args ifso ifnot) ->
+ eval_condition cond (map rs args) m = Some false ->
+ step (State s f sp pc rs m)
+ E0 (State s f sp ifnot rs m)
+ | exec_Lreturn:
+ forall s f stk pc rs m or,
+ (fn_code f)!pc = Some(Lreturn or) ->
+ let rs1 := set_result_reg f.(fn_sig) or rs in
+ let rs2 := return_regs (parent_locset s) rs1 in
+ step (State s f (Vptr stk Int.zero) pc rs m)
+ E0 (Returnstate s f.(fn_sig) rs2 (Mem.free m stk))
+ | exec_function_internal:
+ forall s f rs m m' stk,
+ Mem.alloc m 0 f.(fn_stacksize) = (m', stk) ->
+ let rs1 := call_regs rs in
+ let rs2 := parmov (loc_parameters f.(fn_sig)) f.(fn_params) rs1 in
+ step (Callstate s (Internal f) rs m)
+ E0 (State s f (Vptr stk Int.zero) f.(fn_entrypoint) rs2 m')
+ | exec_function_external:
+ forall s ef t res rs m,
+ let args := map rs (Conventions.loc_arguments ef.(ef_sig)) in
event_match ef args t res ->
- args = List.map rs1 (Conventions.loc_arguments ef.(ef_sig)) ->
- rs2 = Locmap.set (R (Conventions.loc_result ef.(ef_sig))) res rs1 ->
- exec_function (External ef) rs1 m t rs2 m.
+ let rs1 :=
+ Locmap.set (R (Conventions.loc_result ef.(ef_sig))) res rs in
+ step (Callstate s (External ef) rs m)
+ t (Returnstate s ef.(ef_sig) rs1 m)
+ | exec_return:
+ forall res f sp rs0 pc s sig rs m,
+ let rs1 := Locmap.set res (rs (R (loc_result sig))) rs in
+ step (Returnstate (Stackframe res f sp rs0 pc :: s)
+ sig rs m)
+ E0 (State s f sp pc rs1 m).
End RELSEM.
@@ -297,87 +323,41 @@ End RELSEM.
main function, to be found in the machine register dictated
by the calling conventions. *)
-Definition exec_program (p: program) (t: trace) (r: val) : Prop :=
- let ge := Genv.globalenv p in
- let m0 := Genv.init_mem p in
- exists b, exists f, exists rs, exists m,
- Genv.find_symbol ge p.(prog_main) = Some b /\
- Genv.find_funct_ptr ge b = Some f /\
- funsig f = mksignature nil (Some Tint) /\
- exec_function ge f (Locmap.init Vundef) m0 t rs m /\
- rs (R (Conventions.loc_result (funsig f))) = r.
-
-(** We remark that the [exec_blocks] relation is stable if
- the control-flow graph is extended by adding new basic blocks
- at previously unused graph nodes. *)
+Inductive initial_state (p: program): state -> Prop :=
+ | initial_state_intro: forall b f,
+ let ge := Genv.globalenv p in
+ let m0 := Genv.init_mem p in
+ Genv.find_symbol ge p.(prog_main) = Some b ->
+ Genv.find_funct_ptr ge b = Some f ->
+ funsig f = mksignature nil (Some Tint) ->
+ initial_state p (Callstate nil f (Locmap.init Vundef) m0).
-Section EXEC_BLOCKS_EXTENDS.
+Inductive final_state: state -> int -> Prop :=
+ | final_state_intro: forall sig rs m r,
+ rs (R (loc_result sig)) = Vint r ->
+ final_state (Returnstate nil sig rs m) r.
-Variable ge: genv.
-Variable c1 c2: code.
-Hypothesis EXT: forall pc, c2!pc = c1!pc \/ c1!pc = None.
-
-Lemma exec_blocks_extends:
- forall sp pc1 rs1 m1 t out rs2 m2,
- exec_blocks ge c1 sp pc1 rs1 m1 t out rs2 m2 ->
- exec_blocks ge c2 sp pc1 rs1 m1 t out rs2 m2.
-Proof.
- induction 1.
- apply exec_blocks_refl.
- apply exec_blocks_one with b.
- elim (EXT pc); intro; congruence. assumption.
- eapply exec_blocks_trans; eauto.
-Qed.
-
-End EXEC_BLOCKS_EXTENDS.
+Definition exec_program (p: program) (beh: program_behavior) : Prop :=
+ program_behaves step (initial_state p) final_state (Genv.globalenv p) beh.
(** * Operations over LTL *)
-(** Computation of the possible successors of a basic block.
- This is used for dataflow analyses. *)
-
-Fixpoint successors_aux (b: block) : list node :=
- match b with
- | Bgetstack s r b => successors_aux b
- | Bsetstack r s b => successors_aux b
- | Bop op args res b => successors_aux b
- | Bload chunk addr args dst b => successors_aux b
- | Bstore chunk addr args src b => successors_aux b
- | Bcall sig ros b => successors_aux b
- | Balloc b => successors_aux b
- | Bgoto n => n :: nil
- | Bcond cond args ifso ifnot => ifso :: ifnot :: nil
- | Breturn => nil
- end.
+(** Computation of the possible successors of an instruction.
+ This is used in particular for dataflow analyses. *)
Definition successors (f: function) (pc: node) : list node :=
match f.(fn_code)!pc with
| None => nil
- | Some b => successors_aux b
+ | Some i =>
+ match i with
+ | Lnop s => s :: nil
+ | Lop op args res s => s :: nil
+ | Lload chunk addr args dst s => s :: nil
+ | Lstore chunk addr args src s => s :: nil
+ | Lcall sig ros args res s => s :: nil
+ | Ltailcall sig ros args => nil
+ | Lalloc arg res s => s :: nil
+ | Lcond cond args ifso ifnot => ifso :: ifnot :: nil
+ | Lreturn optarg => nil
+ end
end.
-
-Lemma successors_aux_invariant:
- forall ge sp b rs m t b' rs' m',
- exec_instrs ge sp b rs m t b' rs' m' ->
- successors_aux b = successors_aux b'.
-Proof.
- induction 1; simpl; intros.
- reflexivity.
- inversion H; reflexivity.
- transitivity (successors_aux b2); auto.
-Qed.
-
-Lemma successors_correct:
- forall ge f sp pc rs m t pc' rs' m' b,
- f.(fn_code)!pc = Some b ->
- exec_block ge sp b rs m t (Cont pc') rs' m' ->
- In pc' (successors f pc).
-Proof.
- intros. unfold successors. rewrite H. inversion H0.
- rewrite (successors_aux_invariant _ _ _ _ _ _ _ _ _ H7); simpl.
- tauto.
- rewrite (successors_aux_invariant _ _ _ _ _ _ _ _ _ H2); simpl.
- tauto.
- rewrite (successors_aux_invariant _ _ _ _ _ _ _ _ _ H2); simpl.
- tauto.
-Qed.
diff --git a/backend/LTLin.v b/backend/LTLin.v
new file mode 100644
index 0000000..368c13c
--- /dev/null
+++ b/backend/LTLin.v
@@ -0,0 +1,255 @@
+(** The LTLin intermediate language: abstract syntax and semantcs *)
+
+(** The LTLin language is a variant of LTL where control-flow is not
+ expressed as a graph of basic blocks, but as a linear list of
+ instructions with explicit labels and ``goto'' instructions. *)
+
+Require Import Coqlib.
+Require Import Maps.
+Require Import AST.
+Require Import Integers.
+Require Import Values.
+Require Import Mem.
+Require Import Events.
+Require Import Globalenvs.
+Require Import Smallstep.
+Require Import Op.
+Require Import Locations.
+Require Import LTL.
+Require Import Conventions.
+
+(** * Abstract syntax *)
+
+Definition label := positive.
+
+(** LTLin instructions are similar to those of LTL.
+ Except the last three, these instructions continue in sequence
+ with the next instruction in the linear list of instructions.
+ Unconditional branches [Lgoto] and conditional branches [Lcond]
+ transfer control to the given code label. Labels are explicitly
+ inserted in the instruction list as pseudo-instructions [Llabel]. *)
+
+Inductive instruction: Set :=
+ | Lop: operation -> list loc -> loc -> instruction
+ | Lload: memory_chunk -> addressing -> list loc -> loc -> instruction
+ | Lstore: memory_chunk -> addressing -> list loc -> loc -> instruction
+ | Lcall: signature -> loc + ident -> list loc -> loc -> instruction
+ | Ltailcall: signature -> loc + ident -> list loc -> instruction
+ | Lalloc: loc -> loc -> instruction
+ | Llabel: label -> instruction
+ | Lgoto: label -> instruction
+ | Lcond: condition -> list loc -> label -> instruction
+ | Lreturn: option loc -> instruction.
+
+Definition code: Set := list instruction.
+
+Record function: Set := mkfunction {
+ fn_sig: signature;
+ fn_params: list loc;
+ fn_stacksize: Z;
+ fn_code: code
+}.
+
+Definition fundef := AST.fundef function.
+
+Definition program := AST.program fundef unit.
+
+Definition funsig (fd: fundef) :=
+ match fd with
+ | Internal f => f.(fn_sig)
+ | External ef => ef.(ef_sig)
+ end.
+
+Definition genv := Genv.t fundef.
+Definition locset := Locmap.t.
+
+(** * Operational semantics *)
+
+(** Looking up labels in the instruction list. *)
+
+Definition is_label (lbl: label) (instr: instruction) : bool :=
+ match instr with
+ | Llabel lbl' => if peq lbl lbl' then true else false
+ | _ => false
+ end.
+
+Lemma is_label_correct:
+ forall lbl instr,
+ if is_label lbl instr then instr = Llabel lbl else instr <> Llabel lbl.
+Proof.
+ intros. destruct instr; simpl; try discriminate.
+ case (peq lbl l); intro; congruence.
+Qed.
+
+(** [find_label lbl c] returns a list of instruction, suffix of the
+ code [c], that immediately follows the [Llabel lbl] pseudo-instruction.
+ If the label [lbl] is multiply-defined, the first occurrence is
+ retained. If the label [lbl] is not defined, [None] is returned. *)
+
+Fixpoint find_label (lbl: label) (c: code) {struct c} : option code :=
+ match c with
+ | nil => None
+ | i1 :: il => if is_label lbl i1 then Some il else find_label lbl il
+ end.
+
+(** The states of the dynamic semantics are similar to those used
+ in the LTL semantics (see module [LTL]). The only difference
+ is that program points [pc] (nodes of the CFG in LTL) become
+ code sequences [c] (suffixes of the code of the current function).
+*)
+
+Inductive stackframe : Set :=
+ | Stackframe:
+ forall (res: loc) (f: function) (sp: val) (ls: locset) (c: code),
+ stackframe.
+
+Inductive state : Set :=
+ | State:
+ forall (stack: list stackframe) (f: function) (sp: val)
+ (c: code) (ls: locset) (m: mem), state
+ | Callstate:
+ forall (stack: list stackframe) (f: fundef) (ls: locset) (m: mem),
+ state
+ | Returnstate:
+ forall (stack: list stackframe) (sig: signature) (ls: locset) (m: mem),
+ state.
+
+Definition parent_locset (stack: list stackframe) : locset :=
+ match stack with
+ | nil => Locmap.init Vundef
+ | Stackframe res f sp ls pc :: stack' => ls
+ end.
+
+Section RELSEM.
+
+Variable ge: genv.
+
+Definition find_function (ros: loc + ident) (rs: locset) : option fundef :=
+ match ros with
+ | inl r => Genv.find_funct ge (rs r)
+ | inr symb =>
+ match Genv.find_symbol ge symb with
+ | None => None
+ | Some b => Genv.find_funct_ptr ge b
+ end
+ end.
+
+Inductive step: state -> trace -> state -> Prop :=
+ | exec_Lop:
+ forall s f sp op args res b rs m v,
+ eval_operation ge sp op (map rs args) m = Some v ->
+ step (State s f sp (Lop op args res :: b) rs m)
+ E0 (State s f sp b (Locmap.set res v rs) m)
+ | exec_Lload:
+ forall s f sp chunk addr args dst b rs m a v,
+ eval_addressing ge sp addr (map rs args) = Some a ->
+ loadv chunk m a = Some v ->
+ step (State s f sp (Lload chunk addr args dst :: b) rs m)
+ E0 (State s f sp b (Locmap.set dst v rs) m)
+ | exec_Lstore:
+ forall s f sp chunk addr args src b rs m m' a,
+ eval_addressing ge sp addr (map rs args) = Some a ->
+ storev chunk m a (rs src) = Some m' ->
+ step (State s f sp (Lstore chunk addr args src :: b) rs m)
+ E0 (State s f sp b rs m')
+ | exec_Lcall:
+ forall s f sp sig ros args res b rs m f',
+ find_function ros rs = Some f' ->
+ sig = funsig f' ->
+ let rs1 := parmov args (loc_arguments sig) rs in
+ step (State s f sp (Lcall sig ros args res :: b) rs m)
+ E0 (Callstate (Stackframe res f sp rs1 b :: s) f' rs1 m)
+ | exec_Ltailcall:
+ forall s f stk sig ros args b rs m f',
+ find_function ros rs = Some f' ->
+ sig = funsig f' ->
+ let rs1 := parmov args (loc_arguments sig) rs in
+ let rs2 := return_regs (parent_locset s) rs1 in
+ step (State s f (Vptr stk Int.zero) (Ltailcall sig ros args :: b) rs m)
+ E0 (Callstate s f' rs2 (Mem.free m stk))
+ | exec_Lalloc:
+ forall s f sp arg res b rs m sz m' blk,
+ rs arg = Vint sz ->
+ Mem.alloc m 0 (Int.signed sz) = (m', blk) ->
+ let rs1 := Locmap.set (R loc_alloc_argument) (rs arg) rs in
+ let rs2 := Locmap.set (R loc_alloc_result) (Vptr blk Int.zero) rs1 in
+ let rs3 := Locmap.set res (rs2 (R loc_alloc_result)) rs2 in
+ step (State s f sp (Lalloc arg res :: b) rs m)
+ E0 (State s f sp b rs3 m')
+ | exec_Llabel:
+ forall s f sp lbl b rs m,
+ step (State s f sp (Llabel lbl :: b) rs m)
+ E0 (State s f sp b rs m)
+ | exec_Lgoto:
+ forall s f sp lbl b rs m b',
+ find_label lbl f.(fn_code) = Some b' ->
+ step (State s f sp (Lgoto lbl :: b) rs m)
+ E0 (State s f sp b' rs m)
+ | exec_Lcond_true:
+ forall s f sp cond args lbl b rs m b',
+ eval_condition cond (map rs args) m = Some true ->
+ find_label lbl f.(fn_code) = Some b' ->
+ step (State s f sp (Lcond cond args lbl :: b) rs m)
+ E0 (State s f sp b' rs m)
+ | exec_Lcond_false:
+ forall s f sp cond args lbl b rs m,
+ eval_condition cond (map rs args) m = Some false ->
+ step (State s f sp (Lcond cond args lbl :: b) rs m)
+ E0 (State s f sp b rs m)
+ | exec_Lreturn:
+ forall s f stk rs m or b,
+ let rs1 := set_result_reg f.(fn_sig) or rs in
+ let rs2 := return_regs (parent_locset s) rs1 in
+ step (State s f (Vptr stk Int.zero) (Lreturn or :: b) rs m)
+ E0 (Returnstate s f.(fn_sig) rs2 (Mem.free m stk))
+ | exec_function_internal:
+ forall s f rs m m' stk,
+ Mem.alloc m 0 f.(fn_stacksize) = (m', stk) ->
+ let rs1 := call_regs rs in
+ let rs2 := parmov (loc_parameters f.(fn_sig)) f.(fn_params) rs1 in
+ step (Callstate s (Internal f) rs m)
+ E0 (State s f (Vptr stk Int.zero) f.(fn_code) rs2 m')
+ | exec_function_external:
+ forall s ef t res rs m,
+ let args := map rs (Conventions.loc_arguments ef.(ef_sig)) in
+ event_match ef args t res ->
+ let rs1 :=
+ Locmap.set (R (Conventions.loc_result ef.(ef_sig))) res rs in
+ step (Callstate s (External ef) rs m)
+ t (Returnstate s ef.(ef_sig) rs1 m)
+ | exec_return:
+ forall res f sp rs0 b s sig rs m,
+ let rs1 := Locmap.set res (rs (R (loc_result sig))) rs in
+ step (Returnstate (Stackframe res f sp rs0 b :: s) sig rs m)
+ E0 (State s f sp b rs1 m).
+
+End RELSEM.
+
+Inductive initial_state (p: program): state -> Prop :=
+ | initial_state_intro: forall b f,
+ let ge := Genv.globalenv p in
+ let m0 := Genv.init_mem p in
+ Genv.find_symbol ge p.(prog_main) = Some b ->
+ Genv.find_funct_ptr ge b = Some f ->
+ funsig f = mksignature nil (Some Tint) ->
+ initial_state p (Callstate nil f (Locmap.init Vundef) m0).
+
+Inductive final_state: state -> int -> Prop :=
+ | final_state_intro: forall sig rs m r,
+ rs (R (loc_result sig)) = Vint r ->
+ final_state (Returnstate nil sig rs m) r.
+
+Definition exec_program (p: program) (beh: program_behavior) : Prop :=
+ program_behaves step (initial_state p) final_state (Genv.globalenv p) beh.
+
+(** * Properties of the operational semantics *)
+
+Lemma find_label_is_tail:
+ forall lbl c c', find_label lbl c = Some c' -> is_tail c' c.
+Proof.
+ induction c; simpl; intros.
+ discriminate.
+ destruct (is_label lbl a). inv H. constructor. constructor.
+ constructor. auto.
+Qed.
+
diff --git a/backend/LTLintyping.v b/backend/LTLintyping.v
new file mode 100644
index 0000000..06c50f8
--- /dev/null
+++ b/backend/LTLintyping.v
@@ -0,0 +1,104 @@
+(** Typing rules for LTLin. *)
+
+Require Import Coqlib.
+Require Import Maps.
+Require Import AST.
+Require Import Op.
+Require Import RTL.
+Require Import Locations.
+Require Import LTLin.
+Require Import Conventions.
+
+(** The following predicates define a type system for LTLin similar to that
+ of LTL. *)
+
+Section WT_INSTR.
+
+Variable funsig: signature.
+
+Inductive wt_instr : instruction -> Prop :=
+ | wt_Lopmove:
+ forall r1 r,
+ Loc.type r1 = Loc.type r -> loc_acceptable r1 -> loc_acceptable r ->
+ wt_instr (Lop Omove (r1 :: nil) r)
+ | wt_Lop:
+ forall op args res,
+ op <> Omove ->
+ (List.map Loc.type args, Loc.type res) = type_of_operation op ->
+ locs_acceptable args -> loc_acceptable res ->
+ wt_instr (Lop op args res)
+ | wt_Lload:
+ forall chunk addr args dst,
+ List.map Loc.type args = type_of_addressing addr ->
+ Loc.type dst = type_of_chunk chunk ->
+ locs_acceptable args -> loc_acceptable dst ->
+ wt_instr (Lload chunk addr args dst)
+ | wt_Lstore:
+ forall chunk addr args src,
+ List.map Loc.type args = type_of_addressing addr ->
+ Loc.type src = type_of_chunk chunk ->
+ locs_acceptable args -> loc_acceptable src ->
+ wt_instr (Lstore chunk addr args src)
+ | wt_Lcall:
+ forall sig ros args res,
+ match ros with inl r => Loc.type r = Tint | inr s => True end ->
+ List.map Loc.type args = sig.(sig_args) ->
+ Loc.type res = match sig.(sig_res) with None => Tint | Some ty => ty end ->
+ match ros with inl r => loc_acceptable r | inr s => True end ->
+ locs_acceptable args -> loc_acceptable res ->
+ wt_instr (Lcall sig ros args res)
+ | wt_Ltailcall:
+ forall sig ros args,
+ match ros with inl r => Loc.type r = Tint | inr s => True end ->
+ List.map Loc.type args = sig.(sig_args) ->
+ match ros with inl r => loc_acceptable r | inr s => True end ->
+ locs_acceptable args ->
+ sig.(sig_res) = funsig.(sig_res) ->
+ Conventions.tailcall_possible sig ->
+ wt_instr (Ltailcall sig ros args)
+ | wt_Lalloc:
+ forall arg res,
+ Loc.type arg = Tint -> Loc.type res = Tint ->
+ loc_acceptable arg -> loc_acceptable res ->
+ wt_instr (Lalloc arg res)
+ | wt_Llabel: forall lbl,
+ wt_instr (Llabel lbl)
+ | wt_Lgoto: forall lbl,
+ wt_instr (Lgoto lbl)
+ | wt_Lcond:
+ forall cond args lbl,
+ List.map Loc.type args = type_of_condition cond ->
+ locs_acceptable args ->
+ wt_instr (Lcond cond args lbl)
+ | wt_Lreturn:
+ forall optres,
+ option_map Loc.type optres = funsig.(sig_res) ->
+ match optres with None => True | Some r => loc_acceptable r end ->
+ wt_instr (Lreturn optres).
+
+Definition wt_code (c: code) : Prop :=
+ forall i, In i c -> wt_instr i.
+
+End WT_INSTR.
+
+Record wt_function (f: function): Prop :=
+ mk_wt_function {
+ wt_params:
+ List.map Loc.type f.(fn_params) = f.(fn_sig).(sig_args);
+ wt_acceptable:
+ locs_acceptable f.(fn_params);
+ wt_norepet:
+ Loc.norepet f.(fn_params);
+ wt_instrs:
+ wt_code f.(fn_sig) f.(fn_code)
+}.
+
+Inductive wt_fundef: fundef -> Prop :=
+ | wt_fundef_external: forall ef,
+ wt_fundef (External ef)
+ | wt_function_internal: forall f,
+ wt_function f ->
+ wt_fundef (Internal f).
+
+Definition wt_program (p: program): Prop :=
+ forall i f, In (i, f) (prog_funct p) -> wt_fundef f.
diff --git a/backend/LTLtyping.v b/backend/LTLtyping.v
index 187c5cb..646edc8 100644
--- a/backend/LTLtyping.v
+++ b/backend/LTLtyping.v
@@ -13,84 +13,99 @@ Require Import Conventions.
of [RTL] (see file [RTLtyping]): it statically guarantees that operations
and addressing modes are applied to the right number of arguments
and that the arguments are of the correct types. Moreover, it also
- enforces some correctness conditions on the offsets of stack slots
- accessed through [Bgetstack] and [Bsetstack] LTL instructions. *)
+ guarantees that the locations of arguments and results are "acceptable",
+ i.e. either non-temporary registers or [Local] stack locations. *)
-Section WT_BLOCK.
+Section WT_INSTR.
Variable funct: function.
-Definition slot_bounded (s: slot) :=
- match s with
- | Local ofs ty => 0 <= ofs
- | Outgoing ofs ty => 6 <= ofs
- | Incoming ofs ty => 6 <= ofs /\ ofs + typesize ty <= size_arguments funct.(fn_sig)
- end.
+Definition valid_successor (s: node) : Prop :=
+ exists i, funct.(fn_code)!s = Some i.
-Inductive wt_block : block -> Prop :=
- | wt_Bgetstack:
- forall s r b,
- slot_type s = mreg_type r ->
- slot_bounded s ->
- wt_block b ->
- wt_block (Bgetstack s r b)
- | wt_Bsetstack:
- forall r s b,
- match s with Incoming _ _ => False | _ => True end ->
- slot_type s = mreg_type r ->
- slot_bounded s ->
- wt_block b ->
- wt_block (Bsetstack r s b)
- | wt_Bopmove:
- forall r1 r b,
- mreg_type r1 = mreg_type r ->
- wt_block b ->
- wt_block (Bop Omove (r1 :: nil) r b)
- | wt_Bopundef:
- forall r b,
- wt_block b ->
- wt_block (Bop Oundef nil r b)
- | wt_Bop:
- forall op args res b,
- op <> Omove -> op <> Oundef ->
- (List.map mreg_type args, mreg_type res) = type_of_operation op ->
- wt_block b ->
- wt_block (Bop op args res b)
- | wt_Bload:
- forall chunk addr args dst b,
- List.map mreg_type args = type_of_addressing addr ->
- mreg_type dst = type_of_chunk chunk ->
- wt_block b ->
- wt_block (Bload chunk addr args dst b)
- | wt_Bstore:
- forall chunk addr args src b,
- List.map mreg_type args = type_of_addressing addr ->
- mreg_type src = type_of_chunk chunk ->
- wt_block b ->
- wt_block (Bstore chunk addr args src b)
- | wt_Bcall:
- forall sig ros b,
- match ros with inl r => mreg_type r = Tint | _ => True end ->
- wt_block b ->
- wt_block (Bcall sig ros b)
- | wt_Balloc:
- forall b,
- wt_block b ->
- wt_block (Balloc b)
- | wt_Bgoto:
- forall lbl,
- wt_block (Bgoto lbl)
- | wt_Bcond:
- forall cond args ifso ifnot,
- List.map mreg_type args = type_of_condition cond ->
- wt_block (Bcond cond args ifso ifnot)
- | wt_Breturn:
- wt_block (Breturn).
+Inductive wt_instr : instruction -> Prop :=
+ | wt_Lnop:
+ forall s,
+ valid_successor s ->
+ wt_instr (Lnop s)
+ | wt_Lopmove:
+ forall r1 r s,
+ Loc.type r1 = Loc.type r -> loc_acceptable r1 -> loc_acceptable r ->
+ valid_successor s ->
+ wt_instr (Lop Omove (r1 :: nil) r s)
+ | wt_Lop:
+ forall op args res s,
+ op <> Omove ->
+ (List.map Loc.type args, Loc.type res) = type_of_operation op ->
+ locs_acceptable args -> loc_acceptable res ->
+ valid_successor s ->
+ wt_instr (Lop op args res s)
+ | wt_Lload:
+ forall chunk addr args dst s,
+ List.map Loc.type args = type_of_addressing addr ->
+ Loc.type dst = type_of_chunk chunk ->
+ locs_acceptable args -> loc_acceptable dst ->
+ valid_successor s ->
+ wt_instr (Lload chunk addr args dst s)
+ | wt_Lstore:
+ forall chunk addr args src s,
+ List.map Loc.type args = type_of_addressing addr ->
+ Loc.type src = type_of_chunk chunk ->
+ locs_acceptable args -> loc_acceptable src ->
+ valid_successor s ->
+ wt_instr (Lstore chunk addr args src s)
+ | wt_Lcall:
+ forall sig ros args res s,
+ match ros with inl r => Loc.type r = Tint | inr s => True end ->
+ List.map Loc.type args = sig.(sig_args) ->
+ Loc.type res = proj_sig_res sig ->
+ match ros with inl r => loc_acceptable r | inr s => True end ->
+ locs_acceptable args -> loc_acceptable res ->
+ valid_successor s ->
+ wt_instr (Lcall sig ros args res s)
+ | wt_Ltailcall:
+ forall sig ros args,
+ match ros with inl r => Loc.type r = Tint | inr s => True end ->
+ List.map Loc.type args = sig.(sig_args) ->
+ match ros with inl r => loc_acceptable r | inr s => True end ->
+ locs_acceptable args ->
+ sig.(sig_res) = funct.(fn_sig).(sig_res) ->
+ Conventions.tailcall_possible sig ->
+ wt_instr (Ltailcall sig ros args)
+ | wt_Lalloc:
+ forall arg res s,
+ Loc.type arg = Tint -> Loc.type res = Tint ->
+ loc_acceptable arg -> loc_acceptable res ->
+ valid_successor s ->
+ wt_instr (Lalloc arg res s)
+ | wt_Lcond:
+ forall cond args s1 s2,
+ List.map Loc.type args = type_of_condition cond ->
+ locs_acceptable args ->
+ valid_successor s1 -> valid_successor s2 ->
+ wt_instr (Lcond cond args s1 s2)
+ | wt_Lreturn:
+ forall optres,
+ option_map Loc.type optres = funct.(fn_sig).(sig_res) ->
+ match optres with None => True | Some r => loc_acceptable r end ->
+ wt_instr (Lreturn optres).
-End WT_BLOCK.
+End WT_INSTR.
-Definition wt_function (f: function) : Prop :=
- forall pc b, f.(fn_code)!pc = Some b -> wt_block f b.
+Record wt_function (f: function): Prop :=
+ mk_wt_function {
+ wt_params:
+ List.map Loc.type f.(fn_params) = f.(fn_sig).(sig_args);
+ wt_acceptable:
+ locs_acceptable f.(fn_params);
+ wt_norepet:
+ Loc.norepet f.(fn_params);
+ wt_instrs:
+ forall pc instr,
+ f.(fn_code)!pc = Some instr -> wt_instr f instr;
+ wt_entrypoint:
+ valid_successor f f.(fn_entrypoint)
+}.
Inductive wt_fundef: fundef -> Prop :=
| wt_fundef_external: forall ef,
@@ -99,6 +114,5 @@ Inductive wt_fundef: fundef -> Prop :=
wt_function f ->
wt_fundef (Internal f).
-Definition wt_program (p: program) : Prop :=
+Definition wt_program (p: program): Prop :=
forall i f, In (i, f) (prog_funct p) -> wt_fundef f.
-
diff --git a/backend/Linear.v b/backend/Linear.v
index 0f1a31f..6580371 100644
--- a/backend/Linear.v
+++ b/backend/Linear.v
@@ -1,10 +1,10 @@
(** The Linear intermediate language: abstract syntax and semantcs *)
-(** The Linear language is a variant of LTL where control-flow is not
- expressed as a graph of basic blocks, but as a linear list of
- instructions with explicit labels and ``goto'' instructions. *)
+(** The Linear language is a variant of LTLin where arithmetic
+ instructions operate on machine registers (type [mreg]) instead
+ of arbitrary locations. Special instructions [Lgetstack] and
+ [Lsetstack] are provided to access stack slots. *)
-Require Import Relations.
Require Import Coqlib.
Require Import Maps.
Require Import AST.
@@ -13,24 +13,16 @@ Require Import Values.
Require Import Mem.
Require Import Events.
Require Import Globalenvs.
+Require Import Smallstep.
Require Import Op.
Require Import Locations.
Require Import LTL.
-Require Conventions.
+Require Import Conventions.
(** * Abstract syntax *)
Definition label := positive.
-(** Linear instructions are similar to their LTL counterpart:
- arguments and results are machine registers, except for the
- [Lgetstack] and [Lsetstack] instructions which are register-stack moves.
- Except the last three, these instructions continue in sequence
- with the next instruction in the linear list of instructions.
- Unconditional branches [Lgoto] and conditional branches [Lcond]
- transfer control to the given code label. Labels are explicitly
- inserted in the instruction list as pseudo-instructions [Llabel]. *)
-
Inductive instruction: Set :=
| Lgetstack: slot -> mreg -> instruction
| Lsetstack: mreg -> slot -> instruction
@@ -38,6 +30,7 @@ Inductive instruction: Set :=
| Lload: memory_chunk -> addressing -> list mreg -> mreg -> instruction
| Lstore: memory_chunk -> addressing -> list mreg -> mreg -> instruction
| Lcall: signature -> mreg + ident -> instruction
+ | Ltailcall: signature -> mreg + ident -> instruction
| Lalloc: instruction
| Llabel: label -> instruction
| Lgoto: label -> instruction
@@ -108,121 +101,161 @@ Definition find_function (ros: mreg + ident) (rs: locset) : option fundef :=
end
end.
-(** [exec_instr ge f sp c ls m c' ls' m'] represents the execution
- of the first instruction in the code sequence [c]. [ls] and [m]
- are the initial location set and memory state, respectively.
- [c'] is the current code sequence after execution of the instruction:
- it is the tail of [c] if the instruction falls through.
- [ls'] and [m'] are the final location state and memory state. *)
+Definition reglist (rs: locset) (rl: list mreg) : list val :=
+ List.map (fun r => rs (R r)) rl.
+
+(** The components of a Linear execution state are:
+
+- [State cs f sp c rs m]: [f] is the function currently executing.
+ [sp] is the stack pointer. [c] is the sequence of instructions
+ that remain to be executed.
+ [rs] maps locations to their current values. [m] is the current
+ memory state.
+
+- [Callstate cs f rs m]:
+ [f] is the function definition that we are calling.
+ [rs] is the values of locations just before the call.
+ [m] is the current memory state.
+
+- [Returnstate cs rs m]:
+ [rs] is the values of locations just before the return.
+ [m] is the current memory state.
+
+[cs] is a list of stack frames [Stackframe res f rs pc].
+[f] is the calling function, [sp] its stack pointer.
+[rs] the values of locations just before the call.
+[c] is the sequence of instructions following the call in the code of [f].
+*)
+
+Inductive stackframe: Set :=
+ | Stackframe:
+ forall (f: function) (sp: val) (rs: locset) (c: code),
+ stackframe.
+
+Inductive state: Set :=
+ | State:
+ forall (stack: list stackframe) (f: function) (sp: val)
+ (c: code) (rs: locset) (m: mem),
+ state
+ | Callstate:
+ forall (stack: list stackframe) (f: fundef) (rs: locset) (m: mem),
+ state
+ | Returnstate:
+ forall (stack: list stackframe) (rs: locset) (m: mem),
+ state.
-Inductive exec_instr: function -> val ->
- code -> locset -> mem -> trace ->
- code -> locset -> mem -> Prop :=
+(** [parent_locset cs] returns the mapping of values for locations
+ of the caller function. *)
+
+Definition parent_locset (stack: list stackframe) : locset :=
+ match stack with
+ | nil => Locmap.init Vundef
+ | Stackframe f sp ls c :: stack' => ls
+ end.
+
+Inductive step: state -> trace -> state -> Prop :=
| exec_Lgetstack:
- forall f sp sl r b rs m,
- exec_instr f sp (Lgetstack sl r :: b) rs m
- E0 b (Locmap.set (R r) (rs (S sl)) rs) m
+ forall s f sp sl r b rs m,
+ step (State s f sp (Lgetstack sl r :: b) rs m)
+ E0 (State s f sp b (Locmap.set (R r) (rs (S sl)) rs) m)
| exec_Lsetstack:
- forall f sp r sl b rs m,
- exec_instr f sp (Lsetstack r sl :: b) rs m
- E0 b (Locmap.set (S sl) (rs (R r)) rs) m
+ forall s f sp r sl b rs m,
+ step (State s f sp (Lsetstack r sl :: b) rs m)
+ E0 (State s f sp b (Locmap.set (S sl) (rs (R r)) rs) m)
| exec_Lop:
- forall f sp op args res b rs m v,
- eval_operation ge sp op (reglist args rs) = Some v ->
- exec_instr f sp (Lop op args res :: b) rs m
- E0 b (Locmap.set (R res) v rs) m
+ forall s f sp op args res b rs m v,
+ eval_operation ge sp op (reglist rs args) m = Some v ->
+ step (State s f sp (Lop op args res :: b) rs m)
+ E0 (State s f sp b (Locmap.set (R res) v rs) m)
| exec_Lload:
- forall f sp chunk addr args dst b rs m a v,
- eval_addressing ge sp addr (reglist args rs) = Some a ->
+ forall s f sp chunk addr args dst b rs m a v,
+ eval_addressing ge sp addr (reglist rs args) = Some a ->
loadv chunk m a = Some v ->
- exec_instr f sp (Lload chunk addr args dst :: b) rs m
- E0 b (Locmap.set (R dst) v rs) m
+ step (State s f sp (Lload chunk addr args dst :: b) rs m)
+ E0 (State s f sp b (Locmap.set (R dst) v rs) m)
| exec_Lstore:
- forall f sp chunk addr args src b rs m m' a,
- eval_addressing ge sp addr (reglist args rs) = Some a ->
+ forall s f sp chunk addr args src b rs m m' a,
+ eval_addressing ge sp addr (reglist rs args) = Some a ->
storev chunk m a (rs (R src)) = Some m' ->
- exec_instr f sp (Lstore chunk addr args src :: b) rs m
- E0 b rs m'
+ step (State s f sp (Lstore chunk addr args src :: b) rs m)
+ E0 (State s f sp b rs m')
| exec_Lcall:
- forall f sp sig ros b rs m t f' rs' m',
+ forall s f sp sig ros b rs m f',
find_function ros rs = Some f' ->
sig = funsig f' ->
- exec_function f' rs m t rs' m' ->
- exec_instr f sp (Lcall sig ros :: b) rs m
- t b (return_regs rs rs') m'
+ step (State s f sp (Lcall sig ros :: b) rs m)
+ E0 (Callstate (Stackframe f sp rs b:: s) f' rs m)
+ | exec_Ltailcall:
+ forall s f stk sig ros b rs m f',
+ find_function ros rs = Some f' ->
+ sig = funsig f' ->
+ step (State s f (Vptr stk Int.zero) (Ltailcall sig ros :: b) rs m)
+ E0 (Callstate s f' (return_regs (parent_locset s) rs) (Mem.free m stk))
| exec_Lalloc:
- forall f sp b rs m sz m' blk,
+ forall s f sp b rs m sz m' blk,
rs (R Conventions.loc_alloc_argument) = Vint sz ->
Mem.alloc m 0 (Int.signed sz) = (m', blk) ->
- exec_instr f sp (Lalloc :: b) rs m
- E0 b (Locmap.set (R Conventions.loc_alloc_result)
- (Vptr blk Int.zero) rs) m'
+ step (State s f sp (Lalloc :: b) rs m)
+ E0 (State s f sp b
+ (Locmap.set (R Conventions.loc_alloc_result)
+ (Vptr blk Int.zero) rs)
+ m')
| exec_Llabel:
- forall f sp lbl b rs m,
- exec_instr f sp (Llabel lbl :: b) rs m
- E0 b rs m
+ forall s f sp lbl b rs m,
+ step (State s f sp (Llabel lbl :: b) rs m)
+ E0 (State s f sp b rs m)
| exec_Lgoto:
- forall f sp lbl b rs m b',
+ forall s f sp lbl b rs m b',
find_label lbl f.(fn_code) = Some b' ->
- exec_instr f sp (Lgoto lbl :: b) rs m
- E0 b' rs m
+ step (State s f sp (Lgoto lbl :: b) rs m)
+ E0 (State s f sp b' rs m)
| exec_Lcond_true:
- forall f sp cond args lbl b rs m b',
- eval_condition cond (reglist args rs) = Some true ->
+ forall s f sp cond args lbl b rs m b',
+ eval_condition cond (reglist rs args) m = Some true ->
find_label lbl f.(fn_code) = Some b' ->
- exec_instr f sp (Lcond cond args lbl :: b) rs m
- E0 b' rs m
+ step (State s f sp (Lcond cond args lbl :: b) rs m)
+ E0 (State s f sp b' rs m)
| exec_Lcond_false:
- forall f sp cond args lbl b rs m,
- eval_condition cond (reglist args rs) = Some false ->
- exec_instr f sp (Lcond cond args lbl :: b) rs m
- E0 b rs m
-
-with exec_instrs: function -> val ->
- code -> locset -> mem -> trace ->
- code -> locset -> mem -> Prop :=
- | exec_refl:
- forall f sp b rs m,
- exec_instrs f sp b rs m E0 b rs m
- | exec_one:
- forall f sp b1 rs1 m1 t b2 rs2 m2,
- exec_instr f sp b1 rs1 m1 t b2 rs2 m2 ->
- exec_instrs f sp b1 rs1 m1 t b2 rs2 m2
- | exec_trans:
- forall f sp b1 rs1 m1 t1 b2 rs2 m2 t2 b3 rs3 m3 t,
- exec_instrs f sp b1 rs1 m1 t1 b2 rs2 m2 ->
- exec_instrs f sp b2 rs2 m2 t2 b3 rs3 m3 ->
- t = t1 ** t2 ->
- exec_instrs f sp b1 rs1 m1 t b3 rs3 m3
-
-with exec_function: fundef -> locset -> mem -> trace -> locset -> mem -> Prop :=
- | exec_funct_internal:
- forall f rs m t m1 stk rs2 m2 b,
- alloc m 0 f.(fn_stacksize) = (m1, stk) ->
- exec_instrs f (Vptr stk Int.zero)
- f.(fn_code) (call_regs rs) m1
- t (Lreturn :: b) rs2 m2 ->
- exec_function (Internal f) rs m t rs2 (free m2 stk)
- | exec_funct_external:
- forall ef args res rs1 rs2 m t,
+ forall s f sp cond args lbl b rs m,
+ eval_condition cond (reglist rs args) m = Some false ->
+ step (State s f sp (Lcond cond args lbl :: b) rs m)
+ E0 (State s f sp b rs m)
+ | exec_Lreturn:
+ forall s f stk b rs m,
+ step (State s f (Vptr stk Int.zero) (Lreturn :: b) rs m)
+ E0 (Returnstate s (return_regs (parent_locset s) rs) (Mem.free m stk))
+ | exec_function_internal:
+ forall s f rs m m' stk,
+ alloc m 0 f.(fn_stacksize) = (m', stk) ->
+ step (Callstate s (Internal f) rs m)
+ E0 (State s f (Vptr stk Int.zero) f.(fn_code) (call_regs rs) m')
+ | exec_function_external:
+ forall s ef args res rs1 rs2 m t,
event_match ef args t res ->
args = List.map rs1 (Conventions.loc_arguments ef.(ef_sig)) ->
rs2 = Locmap.set (R (Conventions.loc_result ef.(ef_sig))) res rs1 ->
- exec_function (External ef) rs1 m t rs2 m.
-
-Scheme exec_instr_ind3 := Minimality for exec_instr Sort Prop
- with exec_instrs_ind3 := Minimality for exec_instrs Sort Prop
- with exec_function_ind3 := Minimality for exec_function Sort Prop.
+ step (Callstate s (External ef) rs1 m)
+ t (Returnstate s rs2 m)
+ | exec_return:
+ forall s f sp rs0 c rs m,
+ step (Returnstate (Stackframe f sp rs0 c :: s) rs m)
+ E0 (State s f sp c rs m).
End RELSEM.
-Definition exec_program (p: program) (t: trace) (r: val) : Prop :=
- let ge := Genv.globalenv p in
- let m0 := Genv.init_mem p in
- exists b, exists f, exists rs, exists m,
- Genv.find_symbol ge p.(prog_main) = Some b /\
- Genv.find_funct_ptr ge b = Some f /\
- funsig f = mksignature nil (Some Tint) /\
- exec_function ge f (Locmap.init Vundef) m0 t rs m /\
- rs (R (Conventions.loc_result (funsig f))) = r.
+Inductive initial_state (p: program): state -> Prop :=
+ | initial_state_intro: forall b f,
+ let ge := Genv.globalenv p in
+ let m0 := Genv.init_mem p in
+ Genv.find_symbol ge p.(prog_main) = Some b ->
+ Genv.find_funct_ptr ge b = Some f ->
+ funsig f = mksignature nil (Some Tint) ->
+ initial_state p (Callstate nil f (Locmap.init Vundef) m0).
+
+Inductive final_state: state -> int -> Prop :=
+ | final_state_intro: forall rs m r,
+ rs (R R3) = Vint r ->
+ final_state (Returnstate nil rs m) r.
+Definition exec_program (p: program) (beh: program_behavior) : Prop :=
+ program_behaves step (initial_state p) final_state (Genv.globalenv p) beh.
diff --git a/backend/Linearize.v b/backend/Linearize.v
index 3151628..305473b 100644
--- a/backend/Linearize.v
+++ b/backend/Linearize.v
@@ -1,5 +1,5 @@
(** Linearization of the control-flow graph:
- translation from LTL to Linear *)
+ translation from LTL to LTLin *)
Require Import Coqlib.
Require Import Maps.
@@ -9,24 +9,24 @@ Require Import Globalenvs.
Require Import Op.
Require Import Locations.
Require Import LTL.
-Require Import Linear.
+Require Import LTLin.
Require Import Kildall.
Require Import Lattice.
-(** To translate from LTL to Linear, we must layout the basic blocks
+(** To translate from LTL to LTLin, we must lay out the basic blocks
of the LTL control-flow graph in some linear order, and insert
explicit branches and conditional branches to make sure that
each basic block jumps to its successors as prescribed by the
LTL control-flow graph. However, branches are not necessary
- if the fall-through behaviour of Linear instructions already
+ if the fall-through behaviour of LTLin instructions already
implements the desired flow of control. For instance,
- consider the two LTL basic blocks
+ consider the two LTL instructions
<<
- L1: Bop op args res (Bgoto L2)
+ L1: Lop op args res L2
L2: ...
>>
- If the blocks [L1] and [L2] are laid out consecutively in the Linear
- code, we can generate the following Linear code:
+ If the instructions [L1] and [L2] are laid out consecutively in the LTLin
+ code, we can generate the following LTLin code:
<<
L1: Lop op args res
L2: ...
@@ -49,19 +49,13 @@ Require Import Lattice.
- Choosing an order for the basic blocks. This returns an enumeration
of CFG nodes stating that the basic blocks must be laid out in
the order shown in the list.
-- Generate naive Linear code where each basic block branches explicitly
- to its successors, even if one of these successors is the next basic
- block.
-- Simplify the naive Linear code, removing unconditional branches to
- a label that immediately follows:
-<<
- ... ...
- Igoto L1; becomes L1: ...
- L1: ...
->>
+- Generate LTLin code where each basic block branches explicitly
+ to its successors, except if one of these successors is the
+ immediately following instruction.
+
The beauty of this approach is that correct code is generated
under surprisingly weak hypotheses on the enumeration of
- CFG nodes: it suffices that every reachable basic block occurs
+ CFG nodes: it suffices that every reachable instruction occurs
exactly once in the enumeration. While the enumeration heuristic we use
is quite trivial, it is easy to implement more sophisticated
trace picking heuristics: as long as they satisfy the property above,
@@ -73,10 +67,10 @@ Require Import Lattice.
(** * Determination of the order of basic blocks *)
(** We first compute a mapping from CFG nodes to booleans,
- indicating whether a CFG basic block is reachable or not.
+ indicating whether a CFG instruction is reachable or not.
This computation is a trivial forward dataflow analysis
where the transfer function is the identity: the successors
- of a reachable block are reachable, by the very
+ of a reachable instruction are reachable, by the very
definition of reachability. *)
Module DS := Dataflow_Solver(LBoolean)(NodeSetForward).
@@ -84,7 +78,7 @@ Module DS := Dataflow_Solver(LBoolean)(NodeSetForward).
Definition reachable_aux (f: LTL.function) : option (PMap.t bool) :=
DS.fixpoint
(successors f)
- (Psucc f.(fn_entrypoint))
+ (f.(fn_nextpc))
(fun pc r => r)
((f.(fn_entrypoint), true) :: nil).
@@ -108,15 +102,17 @@ Definition enumerate (f: LTL.function) : list node :=
let reach := reachable f in
positive_rec (list node) nil
(fun pc nodes => if reach!!pc then pc :: nodes else nodes)
- (Psucc f.(fn_entrypoint)).
+ f.(fn_nextpc).
-(** * Translation from LTL to Linear *)
+(** * Translation from LTL to LTLin *)
(** We now flatten the structure of the CFG graph, laying out
- basic blocks consecutively in the order computed by [enumerate],
- and inserting a branch at the end of every basic block.
+ LTL instructions consecutively in the order computed by [enumerate],
+ and inserting branches to the labels of sucessors if necessary.
+ Whether to insert a branch or not is determined by
+ the [starts_with] function below.
- For blocks ending in a conditional branch [Bcond cond args s1 s2],
+ For LTL conditional branches [Lcond cond args s1 s2],
we have two possible translations:
<<
Lcond cond args s1; or Lcond (not cond) args s2;
@@ -124,8 +120,8 @@ Definition enumerate (f: LTL.function) : list node :=
>>
We favour the first translation if [s2] is the label of the
next instruction, and the second if [s1] is the label of the
- next instruction, thus exhibiting more opportunities for
- fall-through optimization later. *)
+ next instruction, thus avoiding the insertion of a redundant [Lgoto]
+ instruction. *)
Fixpoint starts_with (lbl: label) (k: code) {struct k} : bool :=
match k with
@@ -133,35 +129,35 @@ Fixpoint starts_with (lbl: label) (k: code) {struct k} : bool :=
| _ => false
end.
-Fixpoint linearize_block (b: block) (k: code) {struct b} : code :=
+Definition add_branch (s: label) (k: code) : code :=
+ if starts_with s k then k else Lgoto s :: k.
+
+Definition linearize_instr (b: LTL.instruction) (k: code) : code :=
match b with
- | Bgetstack s r b =>
- Lgetstack s r :: linearize_block b k
- | Bsetstack r s b =>
- Lsetstack r s :: linearize_block b k
- | Bop op args res b =>
- Lop op args res :: linearize_block b k
- | Bload chunk addr args dst b =>
- Lload chunk addr args dst :: linearize_block b k
- | Bstore chunk addr args src b =>
- Lstore chunk addr args src :: linearize_block b k
- | Bcall sig ros b =>
- Lcall sig ros :: linearize_block b k
- | Balloc b =>
- Lalloc :: linearize_block b k
- | Bgoto s =>
- Lgoto s :: k
- | Bcond cond args s1 s2 =>
+ | LTL.Lnop s =>
+ add_branch s k
+ | LTL.Lop op args res s =>
+ Lop op args res :: add_branch s k
+ | LTL.Lload chunk addr args dst s =>
+ Lload chunk addr args dst :: add_branch s k
+ | LTL.Lstore chunk addr args src s =>
+ Lstore chunk addr args src :: add_branch s k
+ | LTL.Lcall sig ros args res s =>
+ Lcall sig ros args res :: add_branch s k
+ | LTL.Ltailcall sig ros args =>
+ Ltailcall sig ros args :: k
+ | LTL.Lalloc arg res s =>
+ Lalloc arg res :: add_branch s k
+ | LTL.Lcond cond args s1 s2 =>
if starts_with s1 k then
- Lcond (negate_condition cond) args s2 :: Lgoto s1 :: k
+ Lcond (negate_condition cond) args s2 :: add_branch s1 k
else
- Lcond cond args s1 :: Lgoto s2 :: k
- | Breturn =>
- Lreturn :: k
+ Lcond cond args s1 :: add_branch s2 k
+ | LTL.Lreturn or =>
+ Lreturn or :: k
end.
-(* Linearize a function body according to an enumeration of its
- nodes. *)
+(** Linearize a function body according to an enumeration of its nodes. *)
Fixpoint linearize_body (f: LTL.function) (enum: list node)
{struct enum} : code :=
@@ -170,47 +166,21 @@ Fixpoint linearize_body (f: LTL.function) (enum: list node)
| pc :: rem =>
match f.(LTL.fn_code)!pc with
| None => linearize_body f rem
- | Some b => Llabel pc :: linearize_block b (linearize_body f rem)
+ | Some b => Llabel pc :: linearize_instr b (linearize_body f rem)
end
end.
-Definition linearize_function (f: LTL.function) : Linear.function :=
+(** * Entry points for code linearization *)
+
+Definition transf_function (f: LTL.function) : LTLin.function :=
mkfunction
(LTL.fn_sig f)
+ (LTL.fn_params f)
(LTL.fn_stacksize f)
- (linearize_body f (enumerate f)).
-
-(** * Cleanup of the linearized code *)
-
-(** We now eliminate [Lgoto] instructions that branch to an
- immediately following label: these are redundant, as the fall-through
- behaviour obtained by removing the [Lgoto] instruction is
- semantically equivalent. *)
-
-Fixpoint cleanup_code (c: code) {struct c} : code :=
- match c with
- | nil => nil
- | Lgoto lbl :: c' =>
- if starts_with lbl c'
- then cleanup_code c'
- else Lgoto lbl :: cleanup_code c'
- | i :: c' =>
- i :: cleanup_code c'
- end.
-
-Definition cleanup_function (f: Linear.function) : Linear.function :=
- mkfunction
- (fn_sig f)
- (fn_stacksize f)
- (cleanup_code f.(fn_code)).
-
-(** * Entry points for code linearization *)
-
-Definition transf_function (f: LTL.function) : Linear.function :=
- cleanup_function (linearize_function f).
+ (add_branch (LTL.fn_entrypoint f) (linearize_body f (enumerate f))).
-Definition transf_fundef (f: LTL.fundef) : Linear.fundef :=
+Definition transf_fundef (f: LTL.fundef) : LTLin.fundef :=
AST.transf_fundef transf_function f.
-Definition transf_program (p: LTL.program) : Linear.program :=
+Definition transf_program (p: LTL.program) : LTLin.program :=
transform_program transf_fundef p.
diff --git a/backend/Linearizeproof.v b/backend/Linearizeproof.v
index 5937fc3..c729908 100644
--- a/backend/Linearizeproof.v
+++ b/backend/Linearizeproof.v
@@ -8,10 +8,12 @@ Require Import Values.
Require Import Mem.
Require Import Events.
Require Import Globalenvs.
+Require Import Smallstep.
Require Import Op.
Require Import Locations.
Require Import LTL.
-Require Import Linear.
+Require Import LTLtyping.
+Require Import LTLin.
Require Import Linearize.
Require Import Lattice.
@@ -46,6 +48,18 @@ Proof.
destruct f; reflexivity.
Qed.
+Lemma find_function_translated:
+ forall ros ls f,
+ LTL.find_function ge ros ls = Some f ->
+ find_function tge ros ls = Some (transf_fundef f).
+Proof.
+ intros until f. destruct ros; simpl.
+ intro. apply functions_translated; auto.
+ rewrite symbols_preserved. destruct (Genv.find_symbol ge i).
+ apply function_ptr_translated; auto.
+ congruence.
+Qed.
+
(** * Correctness of reachability analysis *)
(** The entry point of the function is reachable. *)
@@ -62,11 +76,10 @@ Proof.
intros. apply PMap.gi.
Qed.
-(** The successors of a reachable basic block are reachable. *)
+(** The successors of a reachable instruction are reachable. *)
Lemma reachable_successors:
forall f pc pc',
- f.(LTL.fn_code)!pc <> None ->
In pc' (successors f pc) ->
(reachable f)!!pc = true ->
(reachable f)!!pc' = true.
@@ -74,51 +87,19 @@ Proof.
intro f. unfold reachable.
caseEq (reachable_aux f).
unfold reachable_aux. intro reach; intros.
+ elim (LTL.fn_code_wf f pc); intro.
assert (LBoolean.ge reach!!pc' reach!!pc).
change (reach!!pc) with ((fun pc r => r) pc (reach!!pc)).
- eapply DS.fixpoint_solution. eexact H.
- elim (fn_code_wf f pc); intro. auto. contradiction.
- auto.
+ eapply DS.fixpoint_solution. eexact H. auto. auto.
elim H3; intro. congruence. auto.
+ unfold successors in H0. rewrite H2 in H0. contradiction.
intros. apply PMap.gi.
Qed.
-(* If we have a valid LTL transition from [pc] to [pc'], and
- [pc] is reachable, then [pc'] is reachable. *)
-
-Lemma reachable_correct_1:
- forall f sp pc rs m t pc' rs' m' b,
- f.(LTL.fn_code)!pc = Some b ->
- exec_block ge sp b rs m t (Cont pc') rs' m' ->
- (reachable f)!!pc = true ->
- (reachable f)!!pc' = true.
-Proof.
- intros. apply reachable_successors with pc; auto.
- congruence.
- eapply successors_correct; eauto.
-Qed.
-
-Lemma reachable_correct_2:
- forall c sp pc rs m t out rs' m',
- exec_blocks ge c sp pc rs m t out rs' m' ->
- forall f pc',
- c = f.(LTL.fn_code) ->
- out = Cont pc' ->
- (reachable f)!!pc = true ->
- (reachable f)!!pc' = true.
-Proof.
- induction 1; intros.
- congruence.
- eapply reachable_correct_1. rewrite <- H1; eauto.
- subst out; eauto. auto.
- auto.
-Qed.
-
(** * Properties of node enumeration *)
(** An enumeration of CFG nodes is correct if the following conditions hold:
- All nodes for reachable basic blocks must be in the list.
-- The function entry point is the first element in the list.
- The list is without repetition (so that no code duplication occurs).
We prove that our [enumerate] function satisfies all three. *)
@@ -131,10 +112,10 @@ Lemma enumerate_complete:
Proof.
intros.
assert (forall p,
- Plt p (Psucc f.(fn_entrypoint)) ->
+ Plt p f.(fn_nextpc) ->
(reachable f)!!p = true ->
In p (enumerate f)).
- unfold enumerate. pattern (Psucc (fn_entrypoint f)).
+ unfold enumerate. pattern (fn_nextpc f).
apply positive_Peano_ind.
intros. compute in H1. destruct p; discriminate.
intros. rewrite positive_rec_succ. elim (Plt_succ_inv _ _ H2); intro.
@@ -143,27 +124,15 @@ Proof.
elim (LTL.fn_code_wf f pc); intro. auto. congruence.
Qed.
-Lemma enumerate_head:
- forall f, exists l, enumerate f = f.(LTL.fn_entrypoint) :: l.
-Proof.
- intro. unfold enumerate. rewrite positive_rec_succ.
- rewrite reachable_entrypoint.
- exists (positive_rec (list node) nil
- (fun (pc : positive) (nodes : list node) =>
- if (reachable f) !! pc then pc :: nodes else nodes)
- (fn_entrypoint f) ).
- auto.
-Qed.
-
Lemma enumerate_norepet:
forall f, list_norepet (enumerate f).
Proof.
intro.
- unfold enumerate. pattern (Psucc (fn_entrypoint f)).
+ unfold enumerate. pattern (fn_nextpc f).
apply positive_Peano_ind.
rewrite positive_rec_base. constructor.
intros. rewrite positive_rec_succ.
- case (reachable f)!!x. auto.
+ case (reachable f)!!x.
constructor.
assert (forall y,
In y (positive_rec
@@ -183,9 +152,9 @@ Proof.
auto.
Qed.
-(** * Correctness of the cleanup pass *)
+(** * Properties related to labels *)
-(** If labels are globally unique and the Linear code [c] contains
+(** If labels are globally unique and the LTLin code [c] contains
a subsequence [Llabel lbl :: c1], [find_label lbl c] returns [c1].
*)
@@ -196,27 +165,6 @@ Fixpoint unique_labels (c: code) : Prop :=
| i :: c => unique_labels c
end.
-Inductive is_tail: code -> code -> Prop :=
- | is_tail_refl:
- forall c, is_tail c c
- | is_tail_cons:
- forall i c1 c2, is_tail c1 c2 -> is_tail c1 (i :: c2).
-
-Lemma is_tail_in:
- forall i c1 c2, is_tail (i :: c1) c2 -> In i c2.
-Proof.
- induction c2; simpl; intros.
- inversion H.
- inversion H. tauto. right; auto.
-Qed.
-
-Lemma is_tail_cons_left:
- forall i c1 c2, is_tail (i :: c1) c2 -> is_tail c1 c2.
-Proof.
- induction c2; intros; inversion H.
- constructor. constructor. constructor. auto.
-Qed.
-
Lemma find_label_unique:
forall lbl c1 c2 c3,
is_tail (Llabel lbl :: c1) c2 ->
@@ -237,163 +185,51 @@ Qed.
(** Correctness of the [starts_with] test. *)
Lemma starts_with_correct:
- forall lbl c1 c2 c3 f sp ls m,
+ forall lbl c1 c2 c3 s f sp ls m,
is_tail c1 c2 ->
unique_labels c2 ->
starts_with lbl c1 = true ->
find_label lbl c2 = Some c3 ->
- exec_instrs tge f sp (cleanup_code c1) ls m
- E0 (cleanup_code c3) ls m.
+ plus step tge (State s f sp c1 ls m)
+ E0 (State s f sp c3 ls m).
Proof.
induction c1.
simpl; intros; discriminate.
simpl starts_with. destruct a; try (intros; discriminate).
- intros. apply exec_trans with E0 (cleanup_code c1) ls m E0.
- simpl.
- constructor. constructor.
+ intros.
+ apply plus_left with E0 (State s f sp c1 ls m) E0.
+ simpl. constructor.
destruct (peq lbl l).
subst l. replace c3 with c1. constructor.
apply find_label_unique with lbl c2; auto.
+ apply plus_star.
apply IHc1 with c2; auto. eapply is_tail_cons_left; eauto.
traceEq.
Qed.
-(** Code cleanup preserves the labeling of the code. *)
-
-Lemma find_label_cleanup_code:
- forall lbl c c',
- find_label lbl c = Some c' ->
- find_label lbl (cleanup_code c) = Some (cleanup_code c').
-Proof.
- induction c.
- simpl. intros; discriminate.
- generalize (is_label_correct lbl a).
- simpl find_label. case (is_label lbl a); intro.
- subst a. intros. injection H; intros. subst c'.
- simpl. rewrite peq_true. auto.
- intros. destruct a; auto.
- simpl. rewrite peq_false. auto.
- congruence.
- case (starts_with l c). auto. simpl. auto.
-Qed.
-
-(** One transition in the original Linear code corresponds to zero
- or one transitions in the cleaned-up code. *)
-
-Lemma cleanup_code_correct_1:
- forall f sp c1 ls1 m1 t c2 ls2 m2,
- exec_instr tge f sp c1 ls1 m1 t c2 ls2 m2 ->
- is_tail c1 f.(fn_code) ->
- unique_labels f.(fn_code) ->
- exec_instrs tge (cleanup_function f) sp
- (cleanup_code c1) ls1 m1
- t (cleanup_code c2) ls2 m2.
-Proof.
- induction 1; simpl; intros;
- try (apply exec_one; econstructor; eauto; fail).
- (* goto *)
- caseEq (starts_with lbl b); intro SW.
- eapply starts_with_correct; eauto.
- eapply is_tail_cons_left; eauto.
- constructor. constructor.
- unfold cleanup_function; simpl.
- apply find_label_cleanup_code. auto.
- (* cond, taken *)
- constructor. apply exec_Lcond_true. auto.
- unfold cleanup_function; simpl.
- apply find_label_cleanup_code. auto.
- (* cond, not taken *)
- constructor. apply exec_Lcond_false. auto.
-Qed.
-
-Lemma is_tail_find_label:
- forall lbl c2 c1,
- find_label lbl c1 = Some c2 -> is_tail c2 c1.
-Proof.
- induction c1; simpl.
- intros; discriminate.
- case (is_label lbl a). intro. injection H; intro. subst c2.
- constructor. constructor.
- intro. constructor. auto.
-Qed.
-
-Lemma is_tail_exec_instr:
- forall f sp c1 ls1 m1 t c2 ls2 m2,
- exec_instr tge f sp c1 ls1 m1 t c2 ls2 m2 ->
- is_tail c1 f.(fn_code) -> is_tail c2 f.(fn_code).
-Proof.
- induction 1; intros;
- try (eapply is_tail_cons_left; eauto; fail).
- eapply is_tail_find_label; eauto.
- eapply is_tail_find_label; eauto.
-Qed.
-
-Lemma is_tail_exec_instrs:
- forall f sp c1 ls1 m1 t c2 ls2 m2,
- exec_instrs tge f sp c1 ls1 m1 t c2 ls2 m2 ->
- is_tail c1 f.(fn_code) -> is_tail c2 f.(fn_code).
-Proof.
- induction 1; intros.
- auto.
- eapply is_tail_exec_instr; eauto.
- auto.
-Qed.
-
-(** Zero, one or several transitions in the original Linear code correspond
- to zero, one or several transitions in the cleaned-up code. *)
-
-Lemma cleanup_code_correct_2:
- forall f sp c1 ls1 m1 t c2 ls2 m2,
- exec_instrs tge f sp c1 ls1 m1 t c2 ls2 m2 ->
- is_tail c1 f.(fn_code) ->
- unique_labels f.(fn_code) ->
- exec_instrs tge (cleanup_function f) sp
- (cleanup_code c1) ls1 m1
- t (cleanup_code c2) ls2 m2.
-Proof.
- induction 1; simpl; intros.
- apply exec_refl.
- eapply cleanup_code_correct_1; eauto.
- apply exec_trans with t1 (cleanup_code b2) rs2 m2 t2.
- auto.
- apply IHexec_instrs2; auto.
- eapply is_tail_exec_instrs; eauto.
- auto.
-Qed.
+(** Connection between [find_label] and linearization. *)
-Lemma cleanup_function_correct:
- forall f ls1 m1 t ls2 m2,
- exec_function tge (Internal f) ls1 m1 t ls2 m2 ->
- unique_labels f.(fn_code) ->
- exec_function tge (Internal (cleanup_function f)) ls1 m1 t ls2 m2.
+Lemma find_label_add_branch:
+ forall lbl k s,
+ find_label lbl (add_branch s k) = find_label lbl k.
Proof.
- intros. inversion H; subst.
- generalize (cleanup_code_correct_2 _ _ _ _ _ _ _ _ _ H3 (is_tail_refl _) H0).
- simpl. intro.
- econstructor; eauto.
+ intros. unfold add_branch. destruct (starts_with s k); auto.
Qed.
-(** * Properties of linearized code *)
-
-(** We now state useful properties of the Linear code generated by
- the naive LTL-to-Linear translation. *)
-
-(** Connection between [find_label] and linearization. *)
-
-Lemma find_label_lin_block:
+Lemma find_label_lin_instr:
forall lbl k b,
- find_label lbl (linearize_block b k) = find_label lbl k.
+ find_label lbl (linearize_instr b k) = find_label lbl k.
Proof.
+ intros lbl k. generalize (find_label_add_branch lbl k); intro.
induction b; simpl; auto.
- case (starts_with n k); reflexivity.
+ case (starts_with n k); simpl; auto.
Qed.
Lemma find_label_lin_rec:
forall f enum pc b,
In pc enum ->
f.(LTL.fn_code)!pc = Some b ->
- exists k,
- find_label pc (linearize_body f enum) = Some (linearize_block b k).
+ exists k, find_label pc (linearize_body f enum) = Some (linearize_instr b k).
Proof.
induction enum; intros.
elim H.
@@ -403,7 +239,7 @@ Proof.
assert (In pc enum). simpl in H. tauto.
elim (IHenum pc b H1 H0). intros k FIND.
exists k. simpl. destruct (LTL.fn_code f)!a.
- simpl. rewrite peq_false. rewrite find_label_lin_block. auto. auto.
+ simpl. rewrite peq_false. rewrite find_label_lin_instr. auto. auto.
auto.
Qed.
@@ -412,20 +248,56 @@ Lemma find_label_lin:
f.(LTL.fn_code)!pc = Some b ->
(reachable f)!!pc = true ->
exists k,
- find_label pc (fn_code (linearize_function f)) = Some (linearize_block b k).
+ find_label pc (fn_code (transf_function f)) = Some (linearize_instr b k).
Proof.
- intros. unfold linearize_function; simpl. apply find_label_lin_rec.
+ intros. unfold transf_function; simpl.
+ rewrite find_label_add_branch. apply find_label_lin_rec.
eapply enumerate_complete; eauto. auto.
Qed.
+Lemma find_label_lin_inv:
+ forall f pc b k ,
+ f.(LTL.fn_code)!pc = Some b ->
+ (reachable f)!!pc = true ->
+ find_label pc (fn_code (transf_function f)) = Some k ->
+ exists k', k = linearize_instr b k'.
+Proof.
+ intros. exploit find_label_lin; eauto. intros [k' FIND].
+ exists k'. congruence.
+Qed.
+
+Lemma find_label_lin_succ:
+ forall f s,
+ valid_successor f s ->
+ (reachable f)!!s = true ->
+ exists k,
+ find_label s (fn_code (transf_function f)) = Some k.
+Proof.
+ intros. destruct H as [i AT].
+ exploit find_label_lin; eauto. intros [k FIND].
+ exists (linearize_instr i k); auto.
+Qed.
+
(** Unique label property for linearized code. *)
-Lemma label_in_lin_block:
+Lemma label_in_add_branch:
+ forall lbl s k,
+ In (Llabel lbl) (add_branch s k) -> In (Llabel lbl) k.
+Proof.
+ intros until k; unfold add_branch.
+ destruct (starts_with s k); simpl; intuition congruence.
+Qed.
+
+Lemma label_in_lin_instr:
forall lbl k b,
- In (Llabel lbl) (linearize_block b k) -> In (Llabel lbl) k.
+ In (Llabel lbl) (linearize_instr b k) -> In (Llabel lbl) k.
Proof.
- induction b; simpl; try (intuition congruence).
- case (starts_with n k); simpl; intuition congruence.
+ induction b; simpl; intros;
+ try (apply label_in_add_branch with n; intuition congruence);
+ try (intuition congruence).
+ destruct (starts_with n k); simpl in H.
+ apply label_in_add_branch with n; intuition congruence.
+ apply label_in_add_branch with n0; intuition congruence.
Qed.
Lemma label_in_lin_rec:
@@ -436,16 +308,24 @@ Proof.
simpl; auto.
simpl. destruct (LTL.fn_code f)!a.
simpl. intros [A|B]. left; congruence.
- right. apply IHenum. eapply label_in_lin_block; eauto.
+ right. apply IHenum. eapply label_in_lin_instr; eauto.
intro; right; auto.
Qed.
-Lemma unique_labels_lin_block:
+Lemma unique_labels_add_branch:
+ forall lbl k,
+ unique_labels k -> unique_labels (add_branch lbl k).
+Proof.
+ intros; unfold add_branch.
+ destruct (starts_with lbl k); simpl; intuition.
+Qed.
+
+Lemma unique_labels_lin_instr:
forall k b,
- unique_labels k -> unique_labels (linearize_block b k).
+ unique_labels k -> unique_labels (linearize_instr b k).
Proof.
- induction b; simpl; auto.
- case (starts_with n k); simpl; auto.
+ induction b; intro; simpl; auto; try (apply unique_labels_add_branch; auto).
+ case (starts_with n k); simpl; apply unique_labels_add_branch; auto.
Qed.
Lemma unique_labels_lin_rec:
@@ -458,268 +338,339 @@ Proof.
intro. simpl. destruct (LTL.fn_code f)!a.
simpl. split. red. intro. inversion H. elim H3.
apply label_in_lin_rec with f.
- apply label_in_lin_block with b. auto.
- apply unique_labels_lin_block. apply IHenum. inversion H; auto.
+ apply label_in_lin_instr with i. auto.
+ apply unique_labels_lin_instr. apply IHenum. inversion H; auto.
apply IHenum. inversion H; auto.
Qed.
-Lemma unique_labels_lin_function:
+Lemma unique_labels_transf_function:
forall f,
- unique_labels (fn_code (linearize_function f)).
+ unique_labels (fn_code (transf_function f)).
Proof.
- intros. unfold linearize_function; simpl.
+ intros. unfold transf_function; simpl.
+ apply unique_labels_add_branch.
apply unique_labels_lin_rec. apply enumerate_norepet.
Qed.
-(** * Correctness of linearization *)
+(** Correctness of [add_branch]. *)
+
+Lemma is_tail_find_label:
+ forall lbl c2 c1,
+ find_label lbl c1 = Some c2 -> is_tail c2 c1.
+Proof.
+ induction c1; simpl.
+ intros; discriminate.
+ case (is_label lbl a). intro. injection H; intro. subst c2.
+ constructor. constructor.
+ intro. constructor. auto.
+Qed.
-(** The outcome of an LTL [exec_block] or [exec_blocks] execution
- is valid if it corresponds to a reachable, existing basic block.
- All outcomes occurring in an LTL program execution are actually
- valid, but we will prove that along with the main simulation proof. *)
+Lemma is_tail_add_branch:
+ forall lbl c1 c2, is_tail (add_branch lbl c1) c2 -> is_tail c1 c2.
+Proof.
+ intros until c2. unfold add_branch. destruct (starts_with lbl c1).
+ auto. eauto with coqlib.
+Qed.
-Definition valid_outcome (f: LTL.function) (out: outcome) :=
- match out with
- | Cont s =>
- (reachable f)!!s = true /\ exists b, f.(LTL.fn_code)!s = Some b
- | Return => True
- end.
+Lemma add_branch_correct:
+ forall lbl c k s f sp ls m,
+ is_tail k (transf_function f).(fn_code) ->
+ find_label lbl (transf_function f).(fn_code) = Some c ->
+ plus step tge (State s (transf_function f) sp (add_branch lbl k) ls m)
+ E0 (State s (transf_function f) sp c ls m).
+Proof.
+ intros. unfold add_branch.
+ caseEq (starts_with lbl k); intro SW.
+ eapply starts_with_correct; eauto.
+ apply unique_labels_transf_function.
+ apply plus_one. apply exec_Lgoto. auto.
+Qed.
-(** Auxiliary lemma used to establish the [valid_outcome] property. *)
+(** * Correctness of linearization *)
-Lemma exec_blocks_valid_outcome:
- forall c sp pc ls1 m1 t out ls2 m2,
- exec_blocks ge c sp pc ls1 m1 t out ls2 m2 ->
- forall f,
- c = f.(LTL.fn_code) ->
- (reachable f)!!pc = true ->
- valid_outcome f out ->
- valid_outcome f (Cont pc).
+(** The proof of semantic preservation is a simulation argument
+ based on diagrams of the following form:
+<<
+ st1 --------------- st2
+ | |
+ t| +|t
+ | |
+ v v
+ st1'--------------- st2'
+>>
+ The invariant (horizontal lines above) is the [match_states]
+ predicate defined below. It captures the fact that the flow
+ of data is the same in the source and linearized codes.
+ Moreover, whenever the source state is at node [pc] in its
+ control-flow graph, the transformed state is at a code
+ sequence [c] that starts with the label [pc]. *)
+
+Inductive match_stackframes: LTL.stackframe -> LTLin.stackframe -> Prop :=
+ | match_stackframe_intro:
+ forall res f sp pc ls c,
+ (reachable f)!!pc = true ->
+ valid_successor f pc ->
+ is_tail c (fn_code (transf_function f)) ->
+ wt_function f ->
+ match_stackframes
+ (LTL.Stackframe res f sp ls pc)
+ (LTLin.Stackframe res (transf_function f) sp ls (add_branch pc c)).
+
+Inductive match_states: LTL.state -> LTLin.state -> Prop :=
+ | match_states_intro:
+ forall s f sp pc ls m ts c
+ (STACKS: list_forall2 match_stackframes s ts)
+ (REACH: (reachable f)!!pc = true)
+ (AT: find_label pc (fn_code (transf_function f)) = Some c)
+ (WTF: wt_function f),
+ match_states (LTL.State s f sp pc ls m)
+ (LTLin.State ts (transf_function f) sp c ls m)
+ | match_states_call:
+ forall s f ls m ts,
+ list_forall2 match_stackframes s ts ->
+ wt_fundef f ->
+ match_states (LTL.Callstate s f ls m)
+ (LTLin.Callstate ts (transf_fundef f) ls m)
+ | match_states_return:
+ forall s sig ls m ts,
+ list_forall2 match_stackframes s ts ->
+ match_states (LTL.Returnstate s sig ls m)
+ (LTLin.Returnstate ts sig ls m).
+
+Remark parent_locset_match:
+ forall s ts,
+ list_forall2 match_stackframes s ts ->
+ parent_locset ts = LTL.parent_locset s.
Proof.
- induction 1.
- auto.
- intros. simpl. split. auto. exists b. congruence.
- intros. apply IHexec_blocks1. auto. auto.
- apply IHexec_blocks2. auto.
- eapply reachable_correct_2. eexact H. auto. auto. auto.
- auto.
+ induction 1; simpl; auto. inv H; auto.
Qed.
-(** Correspondence between an LTL outcome and a fragment of generated
- Linear code. *)
-
-Inductive cont_for_outcome: LTL.function -> outcome -> code -> Prop :=
- | co_return:
- forall f k,
- cont_for_outcome f Return (Lreturn :: k)
- | co_goto:
- forall f s k,
- find_label s (linearize_function f).(fn_code) = Some k ->
- cont_for_outcome f (Cont s) k.
-
-(** The simulation properties used in the inductive proof.
- They are parameterized by an LTL execution, and state
- that a matching execution is possible in the generated Linear code. *)
-
-Definition exec_instr_prop
- (sp: val) (b1: block) (ls1: locset) (m1: mem)
- (t: trace) (b2: block) (ls2: locset) (m2: mem) : Prop :=
- forall f k,
- exec_instr tge (linearize_function f) sp
- (linearize_block b1 k) ls1 m1
- t (linearize_block b2 k) ls2 m2.
-
-Definition exec_instrs_prop
- (sp: val) (b1: block) (ls1: locset) (m1: mem)
- (t: trace) (b2: block) (ls2: locset) (m2: mem) : Prop :=
- forall f k,
- exec_instrs tge (linearize_function f) sp
- (linearize_block b1 k) ls1 m1
- t (linearize_block b2 k) ls2 m2.
-
-Definition exec_block_prop
- (sp: val) (b: block) (ls1: locset) (m1: mem)
- (t: trace) (out: outcome) (ls2: locset) (m2: mem): Prop :=
- forall f k,
- valid_outcome f out ->
- exists k',
- exec_instrs tge (linearize_function f) sp
- (linearize_block b k) ls1 m1
- t k' ls2 m2
- /\ cont_for_outcome f out k'.
-
-Definition exec_blocks_prop
- (c: LTL.code) (sp: val) (pc: node) (ls1: locset) (m1: mem)
- (t: trace) (out: outcome) (ls2: locset) (m2: mem): Prop :=
- forall f k,
- c = f.(LTL.fn_code) ->
- (reachable f)!!pc = true ->
- find_label pc (fn_code (linearize_function f)) = Some k ->
- valid_outcome f out ->
- exists k',
- exec_instrs tge (linearize_function f) sp
- k ls1 m1
- t k' ls2 m2
- /\ cont_for_outcome f out k'.
-
-Definition exec_function_prop
- (f: LTL.fundef) (ls1: locset) (m1: mem) (t: trace)
- (ls2: locset) (m2: mem): Prop :=
- exec_function tge (transf_fundef f) ls1 m1 t ls2 m2.
-
-Scheme exec_instr_ind5 := Minimality for LTL.exec_instr Sort Prop
- with exec_instrs_ind5 := Minimality for LTL.exec_instrs Sort Prop
- with exec_block_ind5 := Minimality for LTL.exec_block Sort Prop
- with exec_blocks_ind5 := Minimality for LTL.exec_blocks Sort Prop
- with exec_function_ind5 := Minimality for LTL.exec_function Sort Prop.
-
-(** The obligatory proof by structural induction on the LTL evaluation
- derivation. *)
-
-Lemma transf_function_correct:
- forall f ls1 m1 t ls2 m2,
- LTL.exec_function ge f ls1 m1 t ls2 m2 ->
- exec_function_prop f ls1 m1 t ls2 m2.
+Hypothesis wt_prog: wt_program prog.
+
+Theorem transf_step_correct:
+ forall s1 t s2, LTL.step ge s1 t s2 ->
+ forall s1' (MS: match_states s1 s1'),
+ exists s2', plus LTLin.step tge s1' t s2' /\ match_states s2 s2'.
Proof.
- apply (exec_function_ind5 ge
- exec_instr_prop
- exec_instrs_prop
- exec_block_prop
- exec_blocks_prop
- exec_function_prop);
- intros; red; intros; simpl.
- (* getstack *)
- constructor.
- (* setstack *)
- constructor.
- (* op *)
- constructor. rewrite <- H. apply eval_operation_preserved.
- exact symbols_preserved.
- (* load *)
- apply exec_Lload with a.
- rewrite <- H. apply eval_addressing_preserved.
- exact symbols_preserved.
- auto.
- (* store *)
- apply exec_Lstore with a.
- rewrite <- H. apply eval_addressing_preserved.
- exact symbols_preserved.
- auto.
- (* call *)
- apply exec_Lcall with (transf_fundef f).
- generalize H. destruct ros; simpl.
- intro; apply functions_translated; auto.
- rewrite symbols_preserved. destruct (Genv.find_symbol ge i).
- intro; apply function_ptr_translated; auto. congruence.
- generalize (sig_preserved f). congruence.
- apply H2.
- (* alloc *)
- eapply exec_Lalloc; eauto.
- (* instr_refl *)
- apply exec_refl.
- (* instr_one *)
- apply exec_one. apply H0.
- (* instr_trans *)
- apply exec_trans with t1 (linearize_block b2 k) rs2 m2 t2.
- apply H0. apply H2. auto.
- (* goto *)
- elim H1. intros REACH [b2 AT2].
- generalize (H0 f k). simpl. intro.
- elim (find_label_lin f s b2 AT2 REACH). intros k2 FIND.
- exists (linearize_block b2 k2).
- split.
- eapply exec_trans. eexact H2. constructor. constructor. auto. traceEq.
- constructor. auto.
- (* cond, true *)
- elim H2. intros REACH [b2 AT2].
- elim (find_label_lin f ifso b2 AT2 REACH). intros k2 FIND.
- exists (linearize_block b2 k2).
- split.
- generalize (H0 f k). simpl.
- case (starts_with ifso k); intro.
- eapply exec_trans. eexact H3.
- eapply exec_trans. apply exec_one. apply exec_Lcond_false.
- change false with (negb true). apply eval_negate_condition. auto.
- apply exec_one. apply exec_Lgoto. auto. reflexivity. traceEq.
- eapply exec_trans. eexact H3.
- apply exec_one. apply exec_Lcond_true.
- auto. auto. traceEq.
- constructor; auto.
- (* cond, false *)
- elim H2. intros REACH [b2 AT2].
- elim (find_label_lin f ifnot b2 AT2 REACH). intros k2 FIND.
- exists (linearize_block b2 k2).
- split.
- generalize (H0 f k). simpl.
- case (starts_with ifso k); intro.
- eapply exec_trans. eexact H3.
- apply exec_one. apply exec_Lcond_true.
- change true with (negb false). apply eval_negate_condition. auto.
- auto. traceEq.
- eapply exec_trans. eexact H3.
- eapply exec_trans. apply exec_one. apply exec_Lcond_false. auto.
- apply exec_one. apply exec_Lgoto. auto. reflexivity. traceEq.
- constructor; auto.
- (* return *)
- exists (Lreturn :: k). split.
- exact (H0 f k). constructor.
- (* refl blocks *)
- exists k. split. apply exec_refl. constructor. auto.
- (* one blocks *)
- subst c. elim (find_label_lin f pc b H H3). intros k' FIND.
- assert (k = linearize_block b k'). congruence. subst k.
- elim (H1 f k' H5). intros k'' [EXEC CFO].
- exists k''. tauto.
- (* trans blocks *)
- assert ((reachable f)!!pc2 = true).
- eapply reachable_correct_2. eexact H. auto. auto. auto.
- assert (valid_outcome f (Cont pc2)).
- eapply exec_blocks_valid_outcome; eauto.
- generalize (H0 f k H4 H5 H6 H9). intros [k1 [EX1 CFO2]].
- inversion CFO2.
- generalize (H2 f k1 H4 H8 H12 H7). intros [k2 [EX2 CFO3]].
- exists k2. split. eapply exec_trans; eauto. auto.
- (* internal function -- TA-DA! *)
- assert (REACH0: (reachable f)!!(fn_entrypoint f) = true).
+ induction 1; intros; try (inv MS);
+ try (generalize (wt_instrs _ WTF _ _ H); intro WTI).
+ (* Lnop *)
+ destruct (find_label_lin_inv _ _ _ _ H REACH AT) as [c' EQ].
+ simpl in EQ. subst c.
+ assert (REACH': (reachable f)!!pc' = true).
+ eapply reachable_successors; eauto.
+ unfold successors; rewrite H; auto with coqlib.
+ exploit find_label_lin_succ; eauto. inv WTI; auto. intros [c'' AT'].
+ econstructor; split.
+ eapply add_branch_correct; eauto.
+ eapply is_tail_add_branch. eapply is_tail_find_label. eauto.
+ econstructor; eauto.
+ (* Lop *)
+ destruct (find_label_lin_inv _ _ _ _ H REACH AT) as [c' EQ].
+ simpl in EQ. subst c.
+ assert (REACH': (reachable f)!!pc' = true).
+ eapply reachable_successors; eauto.
+ unfold successors; rewrite H; auto with coqlib.
+ exploit find_label_lin_succ; eauto. inv WTI; auto. intros [c'' AT'].
+ econstructor; split.
+ eapply plus_left'.
+ eapply exec_Lop with (v := v); eauto.
+ rewrite <- H0. apply eval_operation_preserved. exact symbols_preserved.
+ eapply add_branch_correct; eauto.
+ eapply is_tail_add_branch. eapply is_tail_cons_left.
+ eapply is_tail_find_label. eauto.
+ traceEq.
+ econstructor; eauto.
+ (* Lload *)
+ destruct (find_label_lin_inv _ _ _ _ H REACH AT) as [c' EQ].
+ simpl in EQ. subst c.
+ assert (REACH': (reachable f)!!pc' = true).
+ eapply reachable_successors; eauto.
+ unfold successors; rewrite H; auto with coqlib.
+ exploit find_label_lin_succ; eauto. inv WTI; auto. intros [c'' AT'].
+ econstructor; split.
+ eapply plus_left'.
+ eapply exec_Lload; eauto.
+ rewrite <- H0. apply eval_addressing_preserved. exact symbols_preserved.
+ eapply add_branch_correct; eauto.
+ eapply is_tail_add_branch. eapply is_tail_cons_left.
+ eapply is_tail_find_label. eauto.
+ traceEq.
+ econstructor; eauto.
+ (* Lstore *)
+ destruct (find_label_lin_inv _ _ _ _ H REACH AT) as [c' EQ].
+ simpl in EQ. subst c.
+ assert (REACH': (reachable f)!!pc' = true).
+ eapply reachable_successors; eauto.
+ unfold successors; rewrite H; auto with coqlib.
+ exploit find_label_lin_succ; eauto. inv WTI; auto. intros [c'' AT'].
+ econstructor; split.
+ eapply plus_left'.
+ eapply exec_Lstore; eauto.
+ rewrite <- H0. apply eval_addressing_preserved. exact symbols_preserved.
+ eapply add_branch_correct; eauto.
+ eapply is_tail_add_branch. eapply is_tail_cons_left.
+ eapply is_tail_find_label. eauto.
+ traceEq.
+ econstructor; eauto.
+ (* Lcall *)
+ unfold rs1 in *. inv MS. fold rs1.
+ generalize (wt_instrs _ WTF _ _ H); intro WTI.
+ destruct (find_label_lin_inv _ _ _ _ H REACH AT) as [c' EQ].
+ simpl in EQ. subst c.
+ assert (REACH': (reachable f)!!pc' = true).
+ eapply reachable_successors; eauto.
+ unfold successors; rewrite H; auto with coqlib.
+ assert (VALID: valid_successor f pc'). inv WTI; auto.
+ econstructor; split.
+ apply plus_one. eapply exec_Lcall with (f' := transf_fundef f'); eauto.
+ apply find_function_translated; auto.
+ symmetry; apply sig_preserved.
+ econstructor; eauto.
+ constructor; auto. econstructor; eauto.
+ eapply is_tail_add_branch. eapply is_tail_cons_left.
+ eapply is_tail_find_label. eauto.
+ destruct ros; simpl in H0.
+ eapply Genv.find_funct_prop; eauto.
+ destruct (Genv.find_symbol ge i); try discriminate.
+ eapply Genv.find_funct_ptr_prop; eauto.
+
+ (* Ltailcall *)
+ unfold rs2, rs1 in *. inv MS. fold rs1; fold rs2.
+ destruct (find_label_lin_inv _ _ _ _ H REACH AT) as [c' EQ].
+ simpl in EQ. subst c.
+ econstructor; split.
+ apply plus_one. eapply exec_Ltailcall with (f' := transf_fundef f'); eauto.
+ apply find_function_translated; auto.
+ symmetry; apply sig_preserved.
+ rewrite (parent_locset_match _ _ STACKS).
+ econstructor; eauto.
+ destruct ros; simpl in H0.
+ eapply Genv.find_funct_prop; eauto.
+ destruct (Genv.find_symbol ge i); try discriminate.
+ eapply Genv.find_funct_ptr_prop; eauto.
+
+ (* Lalloc *)
+ destruct (find_label_lin_inv _ _ _ _ H REACH AT) as [c' EQ].
+ simpl in EQ. subst c.
+ assert (REACH': (reachable f)!!pc' = true).
+ eapply reachable_successors; eauto.
+ unfold successors; rewrite H; auto with coqlib.
+ exploit find_label_lin_succ; eauto. inv WTI; auto. intros [c'' AT'].
+ econstructor; split.
+ eapply plus_left'.
+ eapply exec_Lalloc; eauto.
+ eapply add_branch_correct; eauto.
+ eapply is_tail_add_branch. eapply is_tail_cons_left.
+ eapply is_tail_find_label. eauto.
+ traceEq.
+ econstructor; eauto.
+ (* Lcond true *)
+ destruct (find_label_lin_inv _ _ _ _ H REACH AT) as [c' EQ].
+ simpl in EQ. subst c.
+ assert (REACH': (reachable f)!!ifso = true).
+ eapply reachable_successors; eauto.
+ unfold successors; rewrite H; auto with coqlib.
+ exploit find_label_lin_succ; eauto. inv WTI; auto. intros [c'' AT'].
+ destruct (starts_with ifso c').
+ econstructor; split.
+ eapply plus_left'.
+ eapply exec_Lcond_false; eauto.
+ change false with (negb true). apply eval_negate_condition; auto.
+ eapply add_branch_correct; eauto.
+ eapply is_tail_add_branch. eapply is_tail_cons_left.
+ eapply is_tail_find_label. eauto.
+ traceEq.
+ econstructor; eauto.
+ econstructor; split.
+ apply plus_one. eapply exec_Lcond_true; eauto.
+ econstructor; eauto.
+ (* Lcond false *)
+ destruct (find_label_lin_inv _ _ _ _ H REACH AT) as [c' EQ].
+ simpl in EQ. subst c.
+ assert (REACH': (reachable f)!!ifnot = true).
+ eapply reachable_successors; eauto.
+ unfold successors; rewrite H; auto with coqlib.
+ exploit find_label_lin_succ; eauto. inv WTI; auto. intros [c'' AT'].
+ destruct (starts_with ifso c').
+ econstructor; split.
+ apply plus_one. eapply exec_Lcond_true; eauto.
+ change true with (negb false). apply eval_negate_condition; auto.
+ econstructor; eauto.
+ econstructor; split.
+ eapply plus_left'.
+ eapply exec_Lcond_false; eauto.
+ eapply add_branch_correct; eauto.
+ eapply is_tail_add_branch. eapply is_tail_cons_left.
+ eapply is_tail_find_label. eauto.
+ traceEq.
+ econstructor; eauto.
+ (* Lreturn *)
+ destruct (find_label_lin_inv _ _ _ _ H REACH AT) as [c' EQ].
+ simpl in EQ. subst c.
+ econstructor; split.
+ apply plus_one. eapply exec_Lreturn; eauto.
+ rewrite (parent_locset_match _ _ STACKS).
+ econstructor; eauto.
+ (* internal function *)
+ assert (REACH: (reachable f)!!(LTL.fn_entrypoint f) = true).
apply reachable_entrypoint.
- assert (VO2: valid_outcome f Return). simpl; auto.
- assert (VO1: valid_outcome f (Cont (fn_entrypoint f))).
- eapply exec_blocks_valid_outcome; eauto.
- assert (exists k, fn_code (linearize_function f) = Llabel f.(fn_entrypoint) :: k).
- unfold linearize_function; simpl.
- elim (enumerate_head f). intros tl EN. rewrite EN.
- simpl. elim VO1. intros REACH [b EQ]. rewrite EQ.
- exists (linearize_block b (linearize_body f tl)). auto.
- elim H2; intros k EQ.
- assert (find_label (fn_entrypoint f) (fn_code (linearize_function f)) =
- Some k).
- rewrite EQ. simpl. rewrite peq_true. auto.
- generalize (H1 f k (refl_equal _) REACH0 H3 VO2).
- intros [k' [EX CO]].
- inversion CO. subst k'.
- unfold transf_function. apply cleanup_function_correct.
- econstructor. eauto. rewrite EQ. eapply exec_trans.
- apply exec_one. constructor. eauto. traceEq.
- apply unique_labels_lin_function.
+ inv H6.
+ exploit find_label_lin_succ; eauto. inv H1; auto. intros [c'' AT'].
+ simpl. econstructor; split.
+ eapply plus_left'.
+ eapply exec_function_internal; eauto.
+ simpl. eapply add_branch_correct.
+ simpl. eapply is_tail_add_branch. constructor. eauto.
+ traceEq.
+ econstructor; eauto.
(* external function *)
+ simpl. econstructor; split.
+ apply plus_one. eapply exec_function_external; eauto.
+ econstructor; eauto.
+ (* return *)
+ inv H4. inv H1.
+ exploit find_label_lin_succ; eauto. intros [c' AT].
+ econstructor; split.
+ eapply plus_left'.
+ eapply exec_return; eauto.
+ eapply add_branch_correct; eauto. traceEq.
econstructor; eauto.
Qed.
-End LINEARIZATION.
+Lemma transf_initial_states:
+ forall st1, LTL.initial_state prog st1 ->
+ exists st2, LTLin.initial_state tprog st2 /\ match_states st1 st2.
+Proof.
+ intros. inversion H.
+ exists (Callstate nil (transf_fundef f) (Locmap.init Vundef) (Genv.init_mem tprog)); split.
+ econstructor; eauto.
+ change (prog_main tprog) with (prog_main prog).
+ rewrite symbols_preserved. eauto.
+ apply function_ptr_translated; auto.
+ rewrite <- H2. apply sig_preserved.
+ replace (Genv.init_mem tprog) with (Genv.init_mem prog).
+ constructor. constructor.
+ eapply Genv.find_funct_ptr_prop; eauto.
+ symmetry. unfold tprog, transf_program. apply Genv.init_mem_transf.
+Qed.
+
+Lemma transf_final_states:
+ forall st1 st2 r,
+ match_states st1 st2 -> LTL.final_state st1 r -> LTLin.final_state st2 r.
+Proof.
+ intros. inv H0. inv H. inv H6. constructor. auto.
+Qed.
Theorem transf_program_correct:
- forall (p: LTL.program) (t: trace) (r: val),
- LTL.exec_program p t r ->
- Linear.exec_program (transf_program p) t r.
+ forall (beh: program_behavior),
+ LTL.exec_program prog beh -> LTLin.exec_program tprog beh.
Proof.
- intros p t r [b [f [ls [m [FIND1 [FIND2 [SIG [EX RES]]]]]]]].
- red. exists b; exists (transf_fundef f); exists ls; exists m.
- split. change (prog_main (transf_program p)) with (prog_main p).
- rewrite symbols_preserved; auto.
- split. apply function_ptr_translated. auto.
- split. generalize (sig_preserved f); congruence.
- split. apply transf_function_correct.
- unfold transf_program. rewrite Genv.init_mem_transf. auto.
- rewrite sig_preserved. exact RES.
+ unfold LTL.exec_program, exec_program; intros.
+ eapply simulation_plus_preservation; eauto.
+ eexact transf_initial_states.
+ eexact transf_final_states.
+ eexact transf_step_correct.
Qed.
+End LINEARIZATION.
diff --git a/backend/Linearizetyping.v b/backend/Linearizetyping.v
index 66926e9..c930ca5 100644
--- a/backend/Linearizetyping.v
+++ b/backend/Linearizetyping.v
@@ -6,327 +6,72 @@ Require Import AST.
Require Import Op.
Require Import Locations.
Require Import LTL.
-Require Import Linear.
-Require Import Linearize.
Require Import LTLtyping.
-Require Import Lineartyping.
+Require Import LTLin.
+Require Import Linearize.
+Require Import LTLintyping.
Require Import Conventions.
-(** * Validity of resource bounds *)
-
-(** In this section, we show that the resource bounds computed by
- [function_bounds] are valid: all references to callee-save registers
- and stack slots in the code of the function are within those bounds. *)
-
-Section BOUNDS.
-
-Variable f: Linear.function.
-Let b := function_bounds f.
-
-Lemma max_over_list_bound:
- forall (A: Set) (valu: A -> Z) (l: list A) (x: A),
- In x l -> valu x <= max_over_list A valu l.
-Proof.
- intros until x. unfold max_over_list.
- assert (forall c z,
- let f := fold_left (fun x y => Zmax x (valu y)) c z in
- z <= f /\ (In x c -> valu x <= f)).
- induction c; simpl; intros.
- split. omega. tauto.
- elim (IHc (Zmax z (valu a))); intros.
- split. apply Zle_trans with (Zmax z (valu a)). apply Zmax1. auto.
- intro H1; elim H1; intro.
- subst a. apply Zle_trans with (Zmax z (valu x)).
- apply Zmax2. auto. auto.
- intro. elim (H l 0); intros. auto.
-Qed.
-
-Lemma max_over_instrs_bound:
- forall (valu: instruction -> Z) i,
- In i f.(fn_code) -> valu i <= max_over_instrs f valu.
-Proof.
- intros. unfold max_over_instrs. apply max_over_list_bound; auto.
-Qed.
-
-Lemma max_over_regs_of_funct_bound:
- forall (valu: mreg -> Z) i r,
- In i f.(fn_code) -> In r (regs_of_instr i) ->
- valu r <= max_over_regs_of_funct f valu.
-Proof.
- intros. unfold max_over_regs_of_funct.
- apply Zle_trans with (max_over_regs_of_instr valu i).
- unfold max_over_regs_of_instr. apply max_over_list_bound. auto.
- apply max_over_instrs_bound. auto.
-Qed.
-
-Lemma max_over_slots_of_funct_bound:
- forall (valu: slot -> Z) i s,
- In i f.(fn_code) -> In s (slots_of_instr i) ->
- valu s <= max_over_slots_of_funct f valu.
-Proof.
- intros. unfold max_over_slots_of_funct.
- apply Zle_trans with (max_over_slots_of_instr valu i).
- unfold max_over_slots_of_instr. apply max_over_list_bound. auto.
- apply max_over_instrs_bound. auto.
-Qed.
-
-Lemma int_callee_save_bound:
- forall i r,
- In i f.(fn_code) -> In r (regs_of_instr i) ->
- index_int_callee_save r < bound_int_callee_save b.
-Proof.
- intros. apply Zlt_le_trans with (int_callee_save r).
- unfold int_callee_save. omega.
- unfold b, function_bounds, bound_int_callee_save.
- eapply max_over_regs_of_funct_bound; eauto.
-Qed.
-
-Lemma float_callee_save_bound:
- forall i r,
- In i f.(fn_code) -> In r (regs_of_instr i) ->
- index_float_callee_save r < bound_float_callee_save b.
-Proof.
- intros. apply Zlt_le_trans with (float_callee_save r).
- unfold float_callee_save. omega.
- unfold b, function_bounds, bound_float_callee_save.
- eapply max_over_regs_of_funct_bound; eauto.
-Qed.
-
-Lemma int_local_slot_bound:
- forall i ofs,
- In i f.(fn_code) -> In (Local ofs Tint) (slots_of_instr i) ->
- ofs < bound_int_local b.
-Proof.
- intros. apply Zlt_le_trans with (int_local (Local ofs Tint)).
- unfold int_local. omega.
- unfold b, function_bounds, bound_int_local.
- eapply max_over_slots_of_funct_bound; eauto.
-Qed.
-
-Lemma float_local_slot_bound:
- forall i ofs,
- In i f.(fn_code) -> In (Local ofs Tfloat) (slots_of_instr i) ->
- ofs < bound_float_local b.
-Proof.
- intros. apply Zlt_le_trans with (float_local (Local ofs Tfloat)).
- unfold float_local. omega.
- unfold b, function_bounds, bound_float_local.
- eapply max_over_slots_of_funct_bound; eauto.
-Qed.
-
-Lemma outgoing_slot_bound:
- forall i ofs ty,
- In i f.(fn_code) -> In (Outgoing ofs ty) (slots_of_instr i) ->
- ofs + typesize ty <= bound_outgoing b.
-Proof.
- intros. change (ofs + typesize ty) with (outgoing_slot (Outgoing ofs ty)).
- unfold b, function_bounds, bound_outgoing.
- apply Zmax_bound_r. apply Zmax_bound_r.
- eapply max_over_slots_of_funct_bound; eauto.
-Qed.
-
-Lemma size_arguments_bound:
- forall sig ros,
- In (Lcall sig ros) f.(fn_code) ->
- size_arguments sig <= bound_outgoing b.
-Proof.
- intros. change (size_arguments sig) with (outgoing_space (Lcall sig ros)).
- unfold b, function_bounds, bound_outgoing.
- apply Zmax_bound_r. apply Zmax_bound_l.
- apply max_over_instrs_bound; auto.
-Qed.
-
-End BOUNDS.
-
-(** Consequently, all machine registers or stack slots mentioned by one
- of the instructions of function [f] are within bounds. *)
-
-Lemma mreg_is_bounded:
- forall f i r,
- In i f.(fn_code) -> In r (regs_of_instr i) ->
- mreg_bounded f r.
-Proof.
- intros. unfold mreg_bounded.
- case (mreg_type r).
- eapply int_callee_save_bound; eauto.
- eapply float_callee_save_bound; eauto.
-Qed.
-
-Lemma slot_is_bounded:
- forall f i s,
- In i (transf_function f).(fn_code) -> In s (slots_of_instr i) ->
- LTLtyping.slot_bounded f s ->
- slot_bounded (transf_function f) s.
-Proof.
- intros. unfold slot_bounded.
- destruct s.
- destruct t.
- split. exact H1. eapply int_local_slot_bound; eauto.
- split. exact H1. eapply float_local_slot_bound; eauto.
- unfold linearize_function; simpl. exact H1.
- split. exact H1. eapply outgoing_slot_bound; eauto.
-Qed.
-
-(** * Conservation property of the cleanup pass *)
-
-(** We show that the cleanup pass only deletes some [Lgoto] instructions:
- all other instructions present in the output of naive linearization
- are in the cleaned-up code, and all instructions in the cleaned-up code
- are in the output of naive linearization. *)
-
-Lemma cleanup_code_conservation:
- forall i,
- match i with Lgoto _ => False | _ => True end ->
- forall c,
- In i c -> In i (cleanup_code c).
-Proof.
- induction c; simpl.
- auto.
- intro.
- assert (In i (a :: cleanup_code c)).
- elim H0; intro. subst i. auto with coqlib.
- apply in_cons. auto.
- destruct a; auto.
- assert (In i (cleanup_code c)).
- elim H1; intro. subst i. contradiction. auto.
- case (starts_with l c). auto. apply in_cons; auto.
-Qed.
-
-Lemma cleanup_function_conservation:
- forall f i,
- In i (linearize_function f).(fn_code) ->
- match i with Lgoto _ => False | _ => True end ->
- In i (transf_function f).(fn_code).
-Proof.
- intros. unfold transf_function. unfold cleanup_function.
- simpl. simpl in H0. eapply cleanup_code_conservation; eauto.
-Qed.
-
-Lemma cleanup_code_conservation_2:
- forall i c, In i (cleanup_code c) -> In i c.
-Proof.
- induction c; simpl.
- auto.
- assert (In i (a :: cleanup_code c) -> a = i \/ In i c).
- intro. elim H; tauto.
- destruct a; auto.
- case (starts_with l c). auto. auto.
-Qed.
+(** * Type preservation for the linearization pass *)
-Lemma cleanup_function_conservation_2:
- forall f i,
- In i (transf_function f).(fn_code) ->
- In i (linearize_function f).(fn_code).
+Lemma wt_add_instr:
+ forall f i k, wt_instr f i -> wt_code f k -> wt_code f (i :: k).
Proof.
- simpl. intros. eapply cleanup_code_conservation_2; eauto.
+ intros; red; intros. elim H1; intro. subst i0; auto. auto.
Qed.
-(** * Type preservation for the linearization pass *)
-
-Lemma linearize_block_incl:
- forall k b, incl k (linearize_block b k).
+Lemma wt_add_branch:
+ forall f s k, wt_code f k -> wt_code f (add_branch s k).
Proof.
- induction b; simpl; auto with coqlib.
- case (starts_with n k); auto with coqlib.
+ intros; unfold add_branch. destruct (starts_with s k).
+ auto. apply wt_add_instr; auto. constructor.
Qed.
-Lemma wt_linearize_block:
- forall f k,
- (forall i, In i k -> wt_instr (transf_function f) i) ->
- forall b i,
- wt_block f b ->
- incl (linearize_block b k) (linearize_function f).(fn_code) ->
- In i (linearize_block b k) -> wt_instr (transf_function f) i.
+Lemma wt_linearize_instr:
+ forall f instr,
+ LTLtyping.wt_instr f instr ->
+ forall k,
+ wt_code f.(LTL.fn_sig) k ->
+ wt_code f.(LTL.fn_sig) (linearize_instr instr k).
Proof.
- induction b; simpl; intros;
- try (generalize (cleanup_function_conservation
- _ _ (H1 _ (in_eq _ _)) I));
- inversion H0;
- try (elim H2; intro; [subst i|eauto with coqlib]);
- intros.
- (* getstack *)
- constructor. auto. eapply slot_is_bounded; eauto.
- simpl; auto with coqlib.
- eapply mreg_is_bounded; eauto.
- simpl; auto with coqlib.
- (* setstack *)
- constructor. auto. auto.
- eapply slot_is_bounded; eauto.
- simpl; auto with coqlib.
- (* move *)
- subst o; subst l. constructor. auto.
- eapply mreg_is_bounded; eauto.
- simpl; auto with coqlib.
- (* undef *)
- subst o; subst l. constructor.
- eapply mreg_is_bounded; eauto.
- simpl; auto with coqlib.
- (* other ops *)
- constructor; auto.
- eapply mreg_is_bounded; eauto.
- simpl; auto with coqlib.
- (* load *)
- constructor; auto.
- eapply mreg_is_bounded; eauto.
- simpl; auto with coqlib.
- (* store *)
- constructor; auto.
- (* call *)
- constructor; auto.
- eapply size_arguments_bound; eauto.
- (* alloc *)
- constructor.
- (* goto *)
- constructor.
- (* cond *)
- destruct (starts_with n k).
- elim H2; intro.
- subst i. constructor.
- rewrite H4. destruct c; reflexivity.
- elim H8; intro.
- subst i. constructor.
- eauto with coqlib.
- elim H2; intro.
- subst i. constructor. auto.
- elim H8; intro.
- subst i. constructor.
- eauto with coqlib.
- (* return *)
- constructor.
+ induction 1; simpl; intros.
+ apply wt_add_branch; auto.
+ apply wt_add_instr. constructor; auto. apply wt_add_branch; auto.
+ apply wt_add_instr. constructor; auto. apply wt_add_branch; auto.
+ apply wt_add_instr. constructor; auto. apply wt_add_branch; auto.
+ apply wt_add_instr. constructor; auto. apply wt_add_branch; auto.
+ apply wt_add_instr. constructor; auto. apply wt_add_branch; auto.
+ apply wt_add_instr. constructor; auto. auto.
+ apply wt_add_instr. constructor; auto. apply wt_add_branch; auto.
+ destruct (starts_with s1 k); apply wt_add_instr.
+ constructor; auto. rewrite H. destruct cond; auto.
+ apply wt_add_branch; auto.
+ constructor; auto. apply wt_add_branch; auto.
+ apply wt_add_instr. constructor; auto. auto.
Qed.
Lemma wt_linearize_body:
forall f,
- LTLtyping.wt_function f ->
- forall enum i,
- incl (linearize_body f enum) (linearize_function f).(fn_code) ->
- In i (linearize_body f enum) -> wt_instr (transf_function f) i.
-Proof.
- induction enum.
- simpl; intros; contradiction.
- intro i. simpl.
- caseEq (LTL.fn_code f)!a. intros b EQ INCL IN.
- elim IN; intro. subst i; constructor.
- apply wt_linearize_block with (linearize_body f enum) b.
- intros; apply IHenum.
- apply incl_tran with (linearize_block b (linearize_body f enum)).
- apply linearize_block_incl.
- eauto with coqlib.
- auto.
- eapply H; eauto.
- eauto with coqlib. auto.
+ (forall pc instr,
+ f.(LTL.fn_code)!pc = Some instr -> LTLtyping.wt_instr f instr) ->
+ forall enum,
+ wt_code f.(LTL.fn_sig) (linearize_body f enum).
+Proof.
+ induction enum; simpl.
+ red; simpl; intros; contradiction.
+ caseEq ((LTL.fn_code f)!a); intros.
+ apply wt_add_instr. constructor. apply wt_linearize_instr; eauto with coqlib.
auto.
-Qed.
+Qed.
Lemma wt_transf_function:
forall f,
LTLtyping.wt_function f ->
wt_function (transf_function f).
Proof.
- intros; red; intros.
- apply wt_linearize_body with (enumerate f); auto.
- simpl. apply incl_refl.
- apply cleanup_function_conservation_2; auto.
+ intros. inv H. constructor; auto.
+ simpl. apply wt_add_branch.
+ apply wt_linearize_body. auto.
Qed.
Lemma wt_transf_fundef:
@@ -342,7 +87,7 @@ Qed.
Lemma program_typing_preserved:
forall (p: LTL.program),
LTLtyping.wt_program p ->
- Lineartyping.wt_program (transf_program p).
+ LTLintyping.wt_program (transf_program p).
Proof.
intros; red; intros.
generalize (transform_program_function transf_fundef p i f H0).
diff --git a/backend/Lineartyping.v b/backend/Lineartyping.v
index cbe1831..baf522a 100644
--- a/backend/Lineartyping.v
+++ b/backend/Lineartyping.v
@@ -1,4 +1,4 @@
-(** Typing rules and computation of stack bounds for Linear. *)
+(** Typing rules for Linear. *)
Require Import Coqlib.
Require Import Maps.
@@ -9,218 +9,55 @@ Require Import Locations.
Require Import Linear.
Require Import Conventions.
-(** * Resource bounds for a function *)
-
-(** The [bounds] record capture how many local and outgoing stack slots
- and callee-save registers are used by a function. *)
-
-Record bounds : Set := mkbounds {
- bound_int_local: Z;
- bound_float_local: Z;
- bound_int_callee_save: Z;
- bound_float_callee_save: Z;
- bound_outgoing: Z
-}.
-
-(** The resource bounds for a function are computed by a linear scan
- of its instructions. *)
-
-Section BOUNDS.
-
-Variable f: function.
-
-Definition regs_of_instr (i: instruction) : list mreg :=
- match i with
- | Lgetstack s r => r :: nil
- | Lsetstack r s => r :: nil
- | Lop op args res => res :: args
- | Lload chunk addr args dst => dst :: args
- | Lstore chunk addr args src => src :: args
- | Lcall sig (inl fn) => fn :: nil
- | Lcall sig (inr _) => nil
- | Lalloc => nil
- | Llabel lbl => nil
- | Lgoto lbl => nil
- | Lcond cond args lbl => args
- | Lreturn => nil
- end.
-
-Definition slots_of_instr (i: instruction) : list slot :=
- match i with
- | Lgetstack s r => s :: nil
- | Lsetstack r s => s :: nil
- | _ => nil
- end.
-
-Definition max_over_list (A: Set) (valu: A -> Z) (l: list A) : Z :=
- List.fold_left (fun m l => Zmax m (valu l)) l 0.
-
-Definition max_over_instrs (valu: instruction -> Z) : Z :=
- max_over_list instruction valu f.(fn_code).
-
-Definition max_over_regs_of_instr (valu: mreg -> Z) (i: instruction) : Z :=
- max_over_list mreg valu (regs_of_instr i).
-
-Definition max_over_slots_of_instr (valu: slot -> Z) (i: instruction) : Z :=
- max_over_list slot valu (slots_of_instr i).
-
-Definition max_over_regs_of_funct (valu: mreg -> Z) : Z :=
- max_over_instrs (max_over_regs_of_instr valu).
-
-Definition max_over_slots_of_funct (valu: slot -> Z) : Z :=
- max_over_instrs (max_over_slots_of_instr valu).
-
-Definition int_callee_save (r: mreg) := 1 + index_int_callee_save r.
-
-Definition float_callee_save (r: mreg) := 1 + index_float_callee_save r.
-
-Definition int_local (s: slot) :=
- match s with Local ofs Tint => 1 + ofs | _ => 0 end.
-
-Definition float_local (s: slot) :=
- match s with Local ofs Tfloat => 1 + ofs | _ => 0 end.
-
-Definition outgoing_slot (s: slot) :=
- match s with Outgoing ofs ty => ofs + typesize ty | _ => 0 end.
-
-Definition outgoing_space (i: instruction) :=
- match i with Lcall sig _ => size_arguments sig | _ => 0 end.
-
-Definition function_bounds :=
- mkbounds
- (max_over_slots_of_funct int_local)
- (max_over_slots_of_funct float_local)
- (max_over_regs_of_funct int_callee_save)
- (max_over_regs_of_funct float_callee_save)
- (Zmax 6
- (Zmax (max_over_instrs outgoing_space)
- (max_over_slots_of_funct outgoing_slot))).
-
-(** We show that bounds computed by [function_bounds] are all positive
- or null, and moreover [bound_outgoing] is greater or equal to 6.
- These properties are used later to reason about the layout of
- the activation record. *)
-
-Lemma max_over_list_pos:
- forall (A: Set) (valu: A -> Z) (l: list A),
- max_over_list A valu l >= 0.
-Proof.
- intros until valu. unfold max_over_list.
- assert (forall l z, fold_left (fun x y => Zmax x (valu y)) l z >= z).
- induction l; simpl; intros.
- omega. apply Zge_trans with (Zmax z (valu a)).
- auto. apply Zle_ge. apply Zmax1. auto.
-Qed.
-
-Lemma max_over_slots_of_funct_pos:
- forall (valu: slot -> Z), max_over_slots_of_funct valu >= 0.
-Proof.
- intros. unfold max_over_slots_of_funct.
- unfold max_over_instrs. apply max_over_list_pos.
-Qed.
-
-Lemma max_over_regs_of_funct_pos:
- forall (valu: mreg -> Z), max_over_regs_of_funct valu >= 0.
-Proof.
- intros. unfold max_over_regs_of_funct.
- unfold max_over_instrs. apply max_over_list_pos.
-Qed.
-
-Lemma bound_int_local_pos:
- bound_int_local function_bounds >= 0.
-Proof.
- simpl. apply max_over_slots_of_funct_pos.
-Qed.
-
-Lemma bound_float_local_pos:
- bound_float_local function_bounds >= 0.
-Proof.
- simpl. apply max_over_slots_of_funct_pos.
-Qed.
-
-Lemma bound_int_callee_save_pos:
- bound_int_callee_save function_bounds >= 0.
-Proof.
- simpl. apply max_over_regs_of_funct_pos.
-Qed.
-
-Lemma bound_float_callee_save_pos:
- bound_float_callee_save function_bounds >= 0.
-Proof.
- simpl. apply max_over_regs_of_funct_pos.
-Qed.
-
-Lemma bound_outgoing_pos:
- bound_outgoing function_bounds >= 6.
-Proof.
- simpl. apply Zle_ge. apply Zmax_bound_l. omega.
-Qed.
-
-End BOUNDS.
-
-(** * Typing rules for Linear *)
-
-(** The typing rules for Linear are similar to those for LTL: we check
+(** The typing rules for Linear are similar to those for LTLin: we check
that instructions receive the right number of arguments,
and that the types of the argument and result registers agree
- with what the instruction expects. Moreover, we state that references
- to callee-save registers and to stack slots are within the bounds
- computed by [function_bounds]. This is true by construction of
- [function_bounds], and is proved in [Linearizetyping], but it
- is convenient to integrate this property within the typing judgement.
-*)
+ with what the instruction expects. Moreover, we also
+ enforces some correctness conditions on the offsets of stack slots
+ accessed through [Lgetstack] and [Lsetstack] Linear instructions. *)
Section WT_INSTR.
Variable funct: function.
-Let b := function_bounds funct.
-Definition mreg_bounded (r: mreg) :=
- match mreg_type r with
- | Tint => index_int_callee_save r < bound_int_callee_save b
- | Tfloat => index_float_callee_save r < bound_float_callee_save b
+Definition slot_valid (s: slot) :=
+ match s with
+ | Local ofs ty => 0 <= ofs
+ | Outgoing ofs ty => 14 <= ofs
+ | Incoming ofs ty => 14 <= ofs /\ ofs + typesize ty <= size_arguments funct.(fn_sig)
end.
-Definition slot_bounded (s: slot) :=
+Definition slot_writable (s: slot) :=
match s with
- | Local ofs Tint => 0 <= ofs < bound_int_local b
- | Local ofs Tfloat => 0 <= ofs < bound_float_local b
- | Outgoing ofs ty => 6 <= ofs /\ ofs + typesize ty <= bound_outgoing b
- | Incoming ofs ty => 6 <= ofs /\ ofs + typesize ty <= size_arguments funct.(fn_sig)
+ | Local ofs ty => True
+ | Outgoing ofs ty => True
+ | Incoming ofs ty => False
end.
Inductive wt_instr : instruction -> Prop :=
| wt_Lgetstack:
forall s r,
slot_type s = mreg_type r ->
- slot_bounded s -> mreg_bounded r ->
+ slot_valid s ->
wt_instr (Lgetstack s r)
| wt_Lsetstack:
forall s r,
- match s with Incoming _ _ => False | _ => True end ->
slot_type s = mreg_type r ->
- slot_bounded s ->
+ slot_valid s -> slot_writable s ->
wt_instr (Lsetstack r s)
| wt_Lopmove:
forall r1 r,
mreg_type r1 = mreg_type r ->
- mreg_bounded r ->
wt_instr (Lop Omove (r1 :: nil) r)
- | wt_Lopundef:
- forall r,
- mreg_bounded r ->
- wt_instr (Lop Oundef nil r)
| wt_Lop:
forall op args res,
- op <> Omove -> op <> Oundef ->
+ op <> Omove ->
(List.map mreg_type args, mreg_type res) = type_of_operation op ->
- mreg_bounded res ->
wt_instr (Lop op args res)
| wt_Lload:
forall chunk addr args dst,
List.map mreg_type args = type_of_addressing addr ->
mreg_type dst = type_of_chunk chunk ->
- mreg_bounded dst ->
wt_instr (Lload chunk addr args dst)
| wt_Lstore:
forall chunk addr args src,
@@ -229,9 +66,13 @@ Inductive wt_instr : instruction -> Prop :=
wt_instr (Lstore chunk addr args src)
| wt_Lcall:
forall sig ros,
- size_arguments sig <= bound_outgoing b ->
match ros with inl r => mreg_type r = Tint | _ => True end ->
wt_instr (Lcall sig ros)
+ | wt_Ltailcall:
+ forall sig ros,
+ tailcall_possible sig ->
+ match ros with inl r => r = IT3 | _ => True end ->
+ wt_instr (Ltailcall sig ros)
| wt_Lalloc:
wt_instr Lalloc
| wt_Llabel:
@@ -249,8 +90,11 @@ Inductive wt_instr : instruction -> Prop :=
End WT_INSTR.
+Definition wt_code (f: function) (c: code) : Prop :=
+ forall instr, In instr c -> wt_instr f instr.
+
Definition wt_function (f: function) : Prop :=
- forall instr, In instr f.(fn_code) -> wt_instr f instr.
+ wt_code f f.(fn_code).
Inductive wt_fundef: fundef -> Prop :=
| wt_fundef_external: forall ef,
diff --git a/backend/Locations.v b/backend/Locations.v
index c97855e..aaefc08 100644
--- a/backend/Locations.v
+++ b/backend/Locations.v
@@ -434,7 +434,7 @@ End Loc.
(** The [Locmap] module defines mappings from locations to values,
used as evaluation environments for the semantics of the [LTL]
- and [Linear] intermediate languages. *)
+ and [LTLin] intermediate languages. *)
Set Implicit Arguments.
diff --git a/backend/Mach.v b/backend/Mach.v
index f61620d..05805ec 100644
--- a/backend/Mach.v
+++ b/backend/Mach.v
@@ -1,7 +1,8 @@
-(** The Mach intermediate language: abstract syntax and semantics.
+(** The Mach intermediate language: abstract syntax.
Mach is the last intermediate language before generation of assembly
- code.
+ code. This file defines the abstract syntax for Mach; two dynamic
+ semantics are given in modules [Machabstr] and [Machconcr].
*)
Require Import Coqlib.
@@ -14,7 +15,6 @@ Require Import Events.
Require Import Globalenvs.
Require Import Op.
Require Import Locations.
-Require Conventions.
(** * Abstract syntax *)
@@ -30,8 +30,8 @@ Require Conventions.
the caller.
These instructions implement a more concrete view of the activation
- record than the the [Bgetstack] and [Bsetstack] instructions of
- Linear: actual offsets are used instead of abstract stack slots; the
+ record than the the [Lgetstack] and [Lsetstack] instructions of
+ Linear: actual offsets are used instead of abstract stack slots, and the
distinction between the caller's frame and the callee's frame is
made explicit. *)
@@ -45,6 +45,7 @@ Inductive instruction: Set :=
| Mload: memory_chunk -> addressing -> list mreg -> mreg -> instruction
| Mstore: memory_chunk -> addressing -> list mreg -> mreg -> instruction
| Mcall: signature -> mreg + ident -> instruction
+ | Mtailcall: signature -> mreg + ident -> instruction
| Malloc: instruction
| Mlabel: label -> instruction
| Mgoto: label -> instruction
@@ -105,238 +106,25 @@ Fixpoint find_label (lbl: label) (c: code) {struct c} : option code :=
| i1 :: il => if is_label lbl i1 then Some il else find_label lbl il
end.
-(** The three stack-related Mach instructions are interpreted as
- memory accesses relative to the stack pointer. More precisely:
-- [Mgetstack ofs ty r] is a memory load at offset [ofs * 4] relative
- to the stack pointer.
-- [Msetstack r ofs ty] is a memory store at offset [ofs * 4] relative
- to the stack pointer.
-- [Mgetparam ofs ty r] is a memory load at offset [ofs * 4]
- relative to the pointer found at offset 0 from the stack pointer.
- The semantics maintain a linked structure of activation records,
- with the current record containing a pointer to the record of the
- caller function at offset 0. *)
-
-Definition chunk_of_type (ty: typ) :=
- match ty with Tint => Mint32 | Tfloat => Mfloat64 end.
-
-Definition load_stack (m: mem) (sp: val) (ty: typ) (ofs: int) :=
- Mem.loadv (chunk_of_type ty) m (Val.add sp (Vint ofs)).
-
-Definition store_stack (m: mem) (sp: val) (ty: typ) (ofs: int) (v: val) :=
- Mem.storev (chunk_of_type ty) m (Val.add sp (Vint ofs)) v.
-
-Definition align_16_top (lo hi: Z) :=
- Zmax 0 (((hi - lo + 15) / 16) * 16 + lo).
-
-Section RELSEM.
-
-Variable ge: genv.
+Lemma find_label_incl:
+ forall lbl c c', find_label lbl c = Some c' -> incl c' c.
+Proof.
+ induction c; simpl; intros. discriminate.
+ destruct (is_label lbl a). inv H. auto with coqlib. eauto with coqlib.
+Qed.
-Definition find_function (ros: mreg + ident) (rs: regset) : option fundef :=
+Definition find_function_ptr
+ (ge: genv) (ros: mreg + ident) (rs: regset) : option block :=
match ros with
- | inl r => Genv.find_funct ge (rs r)
- | inr symb =>
- match Genv.find_symbol ge symb with
- | None => None
- | Some b => Genv.find_funct_ptr ge b
+ | inl r =>
+ match rs r with
+ | Vptr b ofs => if Int.eq ofs Int.zero then Some b else None
+ | _ => None
end
+ | inr symb =>
+ Genv.find_symbol ge symb
end.
-(** Extract the values of the arguments of an external call. *)
-
-Inductive extcall_arg: regset -> mem -> val -> loc -> val -> Prop :=
- | extcall_arg_reg: forall rs m sp r,
- extcall_arg rs m sp (R r) (rs r)
- | extcall_arg_stack: forall rs m sp ofs ty v,
- load_stack m sp ty (Int.repr (4 * ofs)) = Some v ->
- extcall_arg rs m sp (S (Outgoing ofs ty)) v.
-
-Inductive extcall_args: regset -> mem -> val -> list loc -> list val -> Prop :=
- | extcall_args_nil: forall rs m sp,
- extcall_args rs m sp nil nil
- | extcall_args_cons: forall rs m sp l1 ll v1 vl,
- extcall_arg rs m sp l1 v1 -> extcall_args rs m sp ll vl ->
- extcall_args rs m sp (l1 :: ll) (v1 :: vl).
-
-Definition extcall_arguments
- (rs: regset) (m: mem) (sp: val) (sg: signature) (args: list val) : Prop :=
- extcall_args rs m sp (Conventions.loc_arguments sg) args.
-
-(** [exec_instr ge f sp c rs m c' rs' m'] reflects the execution of
- the first instruction in the current instruction sequence [c].
- [c'] is the current instruction sequence after this execution.
- [rs] and [rs'] map machine registers to values, respectively
- before and after instruction execution. [m] and [m'] are the
- memory states before and after. *)
-
-Inductive exec_instr:
- function -> val ->
- code -> regset -> mem -> trace ->
- code -> regset -> mem -> Prop :=
- | exec_Mlabel:
- forall f sp lbl c rs m,
- exec_instr f sp
- (Mlabel lbl :: c) rs m
- E0 c rs m
- | exec_Mgetstack:
- forall f sp ofs ty dst c rs m v,
- load_stack m sp ty ofs = Some v ->
- exec_instr f sp
- (Mgetstack ofs ty dst :: c) rs m
- E0 c (rs#dst <- v) m
- | exec_Msetstack:
- forall f sp src ofs ty c rs m m',
- store_stack m sp ty ofs (rs src) = Some m' ->
- exec_instr f sp
- (Msetstack src ofs ty :: c) rs m
- E0 c rs m'
- | exec_Mgetparam:
- forall f sp parent ofs ty dst c rs m v,
- load_stack m sp Tint (Int.repr 0) = Some parent ->
- load_stack m parent ty ofs = Some v ->
- exec_instr f sp
- (Mgetparam ofs ty dst :: c) rs m
- E0 c (rs#dst <- v) m
- | exec_Mop:
- forall f sp op args res c rs m v,
- eval_operation ge sp op rs##args = Some v ->
- exec_instr f sp
- (Mop op args res :: c) rs m
- E0 c (rs#res <- v) m
- | exec_Mload:
- forall f sp chunk addr args dst c rs m a v,
- eval_addressing ge sp addr rs##args = Some a ->
- Mem.loadv chunk m a = Some v ->
- exec_instr f sp
- (Mload chunk addr args dst :: c) rs m
- E0 c (rs#dst <- v) m
- | exec_Mstore:
- forall f sp chunk addr args src c rs m m' a,
- eval_addressing ge sp addr rs##args = Some a ->
- Mem.storev chunk m a (rs src) = Some m' ->
- exec_instr f sp
- (Mstore chunk addr args src :: c) rs m
- E0 c rs m'
- | exec_Mcall:
- forall f sp sig ros c rs m f' t rs' m',
- find_function ros rs = Some f' ->
- exec_function f' sp rs m t rs' m' ->
- exec_instr f sp
- (Mcall sig ros :: c) rs m
- t c rs' m'
- | exec_Malloc:
- forall f sp c rs m sz m' blk,
- rs (Conventions.loc_alloc_argument) = Vint sz ->
- Mem.alloc m 0 (Int.signed sz) = (m', blk) ->
- exec_instr f sp
- (Malloc :: c) rs m
- E0 c (rs#Conventions.loc_alloc_result <-
- (Vptr blk Int.zero)) m'
- | exec_Mgoto:
- forall f sp lbl c rs m c',
- find_label lbl f.(fn_code) = Some c' ->
- exec_instr f sp
- (Mgoto lbl :: c) rs m
- E0 c' rs m
- | exec_Mcond_true:
- forall f sp cond args lbl c rs m c',
- eval_condition cond rs##args = Some true ->
- find_label lbl f.(fn_code) = Some c' ->
- exec_instr f sp
- (Mcond cond args lbl :: c) rs m
- E0 c' rs m
- | exec_Mcond_false:
- forall f sp cond args lbl c rs m,
- eval_condition cond rs##args = Some false ->
- exec_instr f sp
- (Mcond cond args lbl :: c) rs m
- E0 c rs m
-
-with exec_instrs:
- function -> val ->
- code -> regset -> mem -> trace ->
- code -> regset -> mem -> Prop :=
- | exec_refl:
- forall f sp c rs m,
- exec_instrs f sp c rs m E0 c rs m
- | exec_one:
- forall f sp c rs m t c' rs' m',
- exec_instr f sp c rs m t c' rs' m' ->
- exec_instrs f sp c rs m t c' rs' m'
- | exec_trans:
- forall f sp c1 rs1 m1 t1 c2 rs2 m2 t2 c3 rs3 m3 t3,
- exec_instrs f sp c1 rs1 m1 t1 c2 rs2 m2 ->
- exec_instrs f sp c2 rs2 m2 t2 c3 rs3 m3 ->
- t3 = t1 ** t2 ->
- exec_instrs f sp c1 rs1 m1 t3 c3 rs3 m3
-
-(** In addition to reserving the word at offset 0 in the activation
- record for maintaining the linking of activation records,
- we need to reserve the word at offset 12 to store the return address
- into the caller. However, the return address (a pointer within
- the code of the caller) is not precisely known at this point:
- it will be determined only after the final translation to PowerPC
- assembly code. Therefore, we simply reserve that word in the strongest
- sense of the word ``reserve'': we make sure that whatever pointer
- is stored there at function entry keeps the same value until the
- final return instruction, and that the return value and final memory
- state are the same regardless of the return address.
- This is captured in the evaluation rule [exec_function]
- that quantifies universally over all possible values of the return
- address, and pass this value to [exec_function_body]. In other
- terms, the inference rule [exec_function] has an infinity of
- premises, one for each possible return address. Such infinitely
- branching inference rules are uncommon in operational semantics,
- but cause no difficulties in Coq. *)
-
-with exec_function_body:
- function -> val -> val ->
- regset -> mem -> trace -> regset -> mem -> Prop :=
- | exec_funct_body:
- forall f parent ra rs m t rs' m1 m2 m3 m4 stk c,
- Mem.alloc m (- f.(fn_framesize))
- (align_16_top (- f.(fn_framesize)) f.(fn_stacksize))
- = (m1, stk) ->
- let sp := Vptr stk (Int.repr (-f.(fn_framesize))) in
- store_stack m1 sp Tint (Int.repr 0) parent = Some m2 ->
- store_stack m2 sp Tint (Int.repr 12) ra = Some m3 ->
- exec_instrs f sp
- f.(fn_code) rs m3
- t (Mreturn :: c) rs' m4 ->
- load_stack m4 sp Tint (Int.repr 0) = Some parent ->
- load_stack m4 sp Tint (Int.repr 12) = Some ra ->
- exec_function_body f parent ra rs m t rs' (Mem.free m4 stk)
-
-with exec_function:
- fundef -> val -> regset -> mem -> trace -> regset -> mem -> Prop :=
- | exec_funct_internal:
- forall f parent rs m t rs' m',
- (forall ra,
- Val.has_type ra Tint ->
- exec_function_body f parent ra rs m t rs' m') ->
- exec_function (Internal f) parent rs m t rs' m'
- | exec_funct_external:
- forall ef parent args res rs1 rs2 m t,
- event_match ef args t res ->
- extcall_arguments rs1 m parent ef.(ef_sig) args ->
- rs2 = (rs1#(Conventions.loc_result ef.(ef_sig)) <- res) ->
- exec_function (External ef) parent rs1 m t rs2 m.
-
-Scheme exec_instr_ind4 := Minimality for exec_instr Sort Prop
- with exec_instrs_ind4 := Minimality for exec_instrs Sort Prop
- with exec_function_body_ind4 := Minimality for exec_function_body Sort Prop
- with exec_function_ind4 := Minimality for exec_function Sort Prop.
-
-End RELSEM.
-
-Definition exec_program (p: program) (t: trace) (r: val) : Prop :=
- let ge := Genv.globalenv p in
- let m0 := Genv.init_mem p in
- exists b, exists f, exists rs, exists m,
- Genv.find_symbol ge p.(prog_main) = Some b /\
- Genv.find_funct_ptr ge b = Some f /\
- exec_function ge f (Vptr Mem.nullptr Int.zero) (Regmap.init Vundef) m0
- t rs m /\
- rs R3 = r.
+Definition align_16_top (lo hi: Z) :=
+ Zmax 0 (((hi - lo + 15) / 16) * 16 + lo).
diff --git a/backend/Machabstr.v b/backend/Machabstr.v
index d83ffa5..ad4e8e1 100644
--- a/backend/Machabstr.v
+++ b/backend/Machabstr.v
@@ -1,4 +1,4 @@
-(** Alternate semantics for the Mach intermediate language. *)
+(** The Mach intermediate language: abstract semantics. *)
Require Import Coqlib.
Require Import Maps.
@@ -9,37 +9,53 @@ Require Import Values.
Require Import Mem.
Require Import Events.
Require Import Globalenvs.
+Require Import Smallstep.
Require Import Op.
Require Import Locations.
Require Conventions.
Require Import Mach.
-(** This file defines an alternate semantics for the Mach intermediate
- language, which differ from the standard semantics given in file [Mach]
- as follows: the stack access instructions [Mgetstack], [Msetstack]
- and [Mgetparam] are interpreted not as memory accesses, but as
- accesses in a frame environment, not resident in memory. The evaluation
- relations take two such frame environments as parameters and results,
- one for the current function and one for its caller.
+(** This file defines the "abstract" semantics for the Mach
+ intermediate language, as opposed to the more concrete
+ semantics given in module [Machconcr].
+
+ The only difference with the concrete semantics is the interpretation
+ of the stack access instructions [Mgetstack], [Msetstack] and [Mgetparam].
+ In the concrete semantics, these are interpreted as memory accesses
+ relative to the stack pointer. In the abstract semantics, these
+ instructions are interpreted as accesses in a frame environment,
+ not resident in memory. The frame environment is an additional
+ component of the state.
Not having the frame data in memory facilitates the proof of
the [Stacking] pass, which shows that the generated code executes
- correctly with the alternate semantics. In file [Machabstr2mach],
- we show an implication from this alternate semantics to
- the standard semantics, thus establishing that the [Stacking] pass
- generates code that behaves correctly against the standard [Mach]
- semantics as well. *)
+ correctly with the abstract semantics.
+*)
(** * Structure of abstract stack frames *)
-(** A frame has the same structure as the contents of a memory block. *)
+(** An abstract stack frame comprises a low bound [fr_low] (the high bound
+ is implicitly 0) and a mapping from (type, offset) pairs to values. *)
+
+Record frame : Set := mkframe {
+ fr_low: Z;
+ fr_contents: typ -> Z -> val
+}.
-Definition frame := block_contents.
+Definition typ_eq: forall (ty1 ty2: typ), {ty1=ty2} + {ty1<>ty2}.
+Proof. decide equality. Defined.
-Definition empty_frame := empty_block 0 0.
+Definition update (ty: typ) (ofs: Z) (v: val) (f: frame) : frame :=
+ mkframe f.(fr_low)
+ (fun ty' ofs' =>
+ if zeq ofs ofs' then
+ if typ_eq ty ty' then v else Vundef
+ else
+ if zle (ofs' + AST.typesize ty') ofs then f.(fr_contents) ty' ofs'
+ else if zle (ofs + AST.typesize ty) ofs' then f.(fr_contents) ty' ofs'
+ else Vundef).
-Definition mem_type (ty: typ) :=
- match ty with Tint => Size32 | Tfloat => Size64 end.
+Definition empty_frame := mkframe 0 (fun ty ofs => Vundef).
(** [get_slot fr ty ofs v] holds if the frame [fr] contains value [v]
with type [ty] at word offset [ofs]. *)
@@ -47,46 +63,24 @@ Definition mem_type (ty: typ) :=
Inductive get_slot: frame -> typ -> Z -> val -> Prop :=
| get_slot_intro:
forall fr ty ofs v,
- 0 <= ofs ->
- fr.(low) + ofs + 4 * typesize ty <= 0 ->
- v = load_contents (mem_type ty) fr.(contents) (fr.(low) + ofs) ->
+ 24 <= ofs ->
+ fr.(fr_low) + ofs + AST.typesize ty <= 0 ->
+ v = fr.(fr_contents) ty (fr.(fr_low) + ofs) ->
get_slot fr ty ofs v.
-Remark size_mem_type:
- forall ty, size_mem (mem_type ty) = 4 * typesize ty.
-Proof.
- destruct ty; reflexivity.
-Qed.
-
-Remark set_slot_undef_outside:
- forall fr ty ofs v,
- fr.(high) = 0 ->
- 0 <= ofs ->
- fr.(low) + ofs + 4 * typesize ty <= 0 ->
- (forall x, x < fr.(low) \/ x >= fr.(high) -> fr.(contents) x = Undef) ->
- (forall x, x < fr.(low) \/ x >= fr.(high) ->
- store_contents (mem_type ty) fr.(contents) (fr.(low) + ofs) v x = Undef).
-Proof.
- intros. apply store_contents_undef_outside with fr.(low) fr.(high).
- rewrite <- size_mem_type in H1. omega. assumption. assumption.
-Qed.
-
(** [set_slot fr ty ofs v fr'] holds if frame [fr'] is obtained from
frame [fr] by storing value [v] with type [ty] at word offset [ofs]. *)
Inductive set_slot: frame -> typ -> Z -> val -> frame -> Prop :=
| set_slot_intro:
- forall fr ty ofs v
- (A: fr.(high) = 0)
- (B: 0 <= ofs)
- (C: fr.(low) + ofs + 4 * typesize ty <= 0),
- set_slot fr ty ofs v
- (mkblock fr.(low) fr.(high)
- (store_contents (mem_type ty) fr.(contents) (fr.(low) + ofs) v)
- (set_slot_undef_outside fr ty ofs v A B C fr.(undef_outside))).
+ forall fr ty ofs v fr',
+ 24 <= ofs ->
+ fr.(fr_low) + ofs + AST.typesize ty <= 0 ->
+ fr' = update ty (fr.(fr_low) + ofs) v fr ->
+ set_slot fr ty ofs v fr'.
Definition init_frame (f: function) :=
- empty_block (- f.(fn_framesize)) 0.
+ mkframe (- f.(fn_framesize)) (fun ty ofs => Vundef).
(** Extract the values of the arguments of an external call. *)
@@ -108,320 +102,172 @@ Definition extcall_arguments
(rs: regset) (fr: frame) (sg: signature) (args: list val) : Prop :=
extcall_args rs fr (Conventions.loc_arguments sg) args.
+(** The components of an execution state are:
+
+- [State cs f sp c rs fr m]: [f] is the function currently executing.
+ [sp] is the stack pointer. [c] is the list of instructions that
+ remain to be executed. [rs] assigns values to registers.
+ [fr] is the current frame, as described above. [m] is the memory state.
+- [Callstate cs f rs m]: [f] is the function definition being called.
+ [rs] is the current values of registers,
+ and [m] the current memory state.
+- [Returnstate cs rs m]: [rs] is the current values of registers,
+ and [m] the current memory state.
+
+[cs] is a list of stack frames [Stackframe f sp c fr],
+where [f] is the block reference for the calling function,
+[c] the code within this function that follows the call instruction,
+[sp] its stack pointer, and [fr] its private frame. *)
+
+Inductive stackframe: Set :=
+ | Stackframe:
+ forall (f: function) (sp: val) (c: code) (fr: frame),
+ stackframe.
+
+Inductive state: Set :=
+ | State:
+ forall (stack: list stackframe) (f: function) (sp: val)
+ (c: code) (rs: regset) (fr: frame) (m: mem),
+ state
+ | Callstate:
+ forall (stack: list stackframe) (f: fundef) (rs: regset) (m: mem),
+ state
+ | Returnstate:
+ forall (stack: list stackframe) (rs: regset) (m: mem),
+ state.
+
+(** [parent_frame s] returns the frame of the calling function.
+ It is used to access function parameters that are passed on the stack
+ (the [Mgetparent] instruction). *)
+
+Definition parent_frame (s: list stackframe) : frame :=
+ match s with
+ | nil => empty_frame
+ | Stackframe f sp c fr :: s => fr
+ end.
+
Section RELSEM.
Variable ge: genv.
-(** Execution of one instruction has the form
- [exec_instr ge f sp parent c rs fr m c' rs' fr' m'],
- where [parent] is the caller's frame (read-only)
- and [fr], [fr'] are the current frame, before and after execution
- of one instruction. The other parameters are as in the Mach semantics. *)
+Definition find_function (ros: mreg + ident) (rs: regset) : option fundef :=
+ match ros with
+ | inl r => Genv.find_funct ge (rs r)
+ | inr symb =>
+ match Genv.find_symbol ge symb with
+ | None => None
+ | Some b => Genv.find_funct_ptr ge b
+ end
+ end.
-Inductive exec_instr:
- function -> val -> frame ->
- code -> regset -> frame -> mem -> trace ->
- code -> regset -> frame -> mem -> Prop :=
+Inductive step: state -> trace -> state -> Prop :=
| exec_Mlabel:
- forall f sp parent lbl c rs fr m,
- exec_instr f sp parent
- (Mlabel lbl :: c) rs fr m
- E0 c rs fr m
+ forall s f sp lbl c rs fr m,
+ step (State s f sp (Mlabel lbl :: c) rs fr m)
+ E0 (State s f sp c rs fr m)
| exec_Mgetstack:
- forall f sp parent ofs ty dst c rs fr m v,
+ forall s f sp ofs ty dst c rs fr m v,
get_slot fr ty (Int.signed ofs) v ->
- exec_instr f sp parent
- (Mgetstack ofs ty dst :: c) rs fr m
- E0 c (rs#dst <- v) fr m
+ step (State s f sp (Mgetstack ofs ty dst :: c) rs fr m)
+ E0 (State s f sp c (rs#dst <- v) fr m)
| exec_Msetstack:
- forall f sp parent src ofs ty c rs fr m fr',
+ forall s f sp src ofs ty c rs fr m fr',
set_slot fr ty (Int.signed ofs) (rs src) fr' ->
- exec_instr f sp parent
- (Msetstack src ofs ty :: c) rs fr m
- E0 c rs fr' m
+ step (State s f sp (Msetstack src ofs ty :: c) rs fr m)
+ E0 (State s f sp c rs fr' m)
| exec_Mgetparam:
- forall f sp parent ofs ty dst c rs fr m v,
- get_slot parent ty (Int.signed ofs) v ->
- exec_instr f sp parent
- (Mgetparam ofs ty dst :: c) rs fr m
- E0 c (rs#dst <- v) fr m
+ forall s f sp ofs ty dst c rs fr m v,
+ get_slot (parent_frame s) ty (Int.signed ofs) v ->
+ step (State s f sp (Mgetparam ofs ty dst :: c) rs fr m)
+ E0 (State s f sp c (rs#dst <- v) fr m)
| exec_Mop:
- forall f sp parent op args res c rs fr m v,
- eval_operation ge sp op rs##args = Some v ->
- exec_instr f sp parent
- (Mop op args res :: c) rs fr m
- E0 c (rs#res <- v) fr m
+ forall s f sp op args res c rs fr m v,
+ eval_operation ge sp op rs##args m = Some v ->
+ step (State s f sp (Mop op args res :: c) rs fr m)
+ E0 (State s f sp c (rs#res <- v) fr m)
| exec_Mload:
- forall f sp parent chunk addr args dst c rs fr m a v,
+ forall s f sp chunk addr args dst c rs fr m a v,
eval_addressing ge sp addr rs##args = Some a ->
Mem.loadv chunk m a = Some v ->
- exec_instr f sp parent
- (Mload chunk addr args dst :: c) rs fr m
- E0 c (rs#dst <- v) fr m
+ step (State s f sp (Mload chunk addr args dst :: c) rs fr m)
+ E0 (State s f sp c (rs#dst <- v) fr m)
| exec_Mstore:
- forall f sp parent chunk addr args src c rs fr m m' a,
+ forall s f sp chunk addr args src c rs fr m m' a,
eval_addressing ge sp addr rs##args = Some a ->
Mem.storev chunk m a (rs src) = Some m' ->
- exec_instr f sp parent
- (Mstore chunk addr args src :: c) rs fr m
- E0 c rs fr m'
+ step (State s f sp (Mstore chunk addr args src :: c) rs fr m)
+ E0 (State s f sp c rs fr m')
| exec_Mcall:
- forall f sp parent sig ros c rs fr m t f' rs' m',
- find_function ge ros rs = Some f' ->
- exec_function f' fr rs m t rs' m' ->
- exec_instr f sp parent
- (Mcall sig ros :: c) rs fr m
- t c rs' fr m'
+ forall s f sp sig ros c rs fr m f',
+ find_function ros rs = Some f' ->
+ step (State s f sp (Mcall sig ros :: c) rs fr m)
+ E0 (Callstate (Stackframe f sp c fr :: s) f' rs m)
+ | exec_Mtailcall:
+ forall s f stk soff sig ros c rs fr m f',
+ find_function ros rs = Some f' ->
+ step (State s f (Vptr stk soff) (Mtailcall sig ros :: c) rs fr m)
+ E0 (Callstate s f' rs (Mem.free m stk))
+
| exec_Malloc:
- forall f sp parent c rs fr m sz m' blk,
+ forall s f sp c rs fr m sz m' blk,
rs (Conventions.loc_alloc_argument) = Vint sz ->
Mem.alloc m 0 (Int.signed sz) = (m', blk) ->
- exec_instr f sp parent
- (Malloc :: c) rs fr m
- E0 c (rs#Conventions.loc_alloc_result <-
- (Vptr blk Int.zero)) fr m'
+ step (State s f sp (Malloc :: c) rs fr m)
+ E0 (State s f sp c
+ (rs#Conventions.loc_alloc_result <- (Vptr blk Int.zero))
+ fr m')
| exec_Mgoto:
- forall f sp parent lbl c rs fr m c',
+ forall s f sp lbl c rs fr m c',
find_label lbl f.(fn_code) = Some c' ->
- exec_instr f sp parent
- (Mgoto lbl :: c) rs fr m
- E0 c' rs fr m
+ step (State s f sp (Mgoto lbl :: c) rs fr m)
+ E0 (State s f sp c' rs fr m)
| exec_Mcond_true:
- forall f sp parent cond args lbl c rs fr m c',
- eval_condition cond rs##args = Some true ->
+ forall s f sp cond args lbl c rs fr m c',
+ eval_condition cond rs##args m = Some true ->
find_label lbl f.(fn_code) = Some c' ->
- exec_instr f sp parent
- (Mcond cond args lbl :: c) rs fr m
- E0 c' rs fr m
+ step (State s f sp (Mcond cond args lbl :: c) rs fr m)
+ E0 (State s f sp c' rs fr m)
| exec_Mcond_false:
- forall f sp parent cond args lbl c rs fr m,
- eval_condition cond rs##args = Some false ->
- exec_instr f sp parent
- (Mcond cond args lbl :: c) rs fr m
- E0 c rs fr m
-
-with exec_instrs:
- function -> val -> frame ->
- code -> regset -> frame -> mem -> trace ->
- code -> regset -> frame -> mem -> Prop :=
- | exec_refl:
- forall f sp parent c rs fr m,
- exec_instrs f sp parent c rs fr m E0 c rs fr m
- | exec_one:
- forall f sp parent c rs fr m t c' rs' fr' m',
- exec_instr f sp parent c rs fr m t c' rs' fr' m' ->
- exec_instrs f sp parent c rs fr m t c' rs' fr' m'
- | exec_trans:
- forall f sp parent c1 rs1 fr1 m1 t1 c2 rs2 fr2 m2 t2 c3 rs3 fr3 m3 t3,
- exec_instrs f sp parent c1 rs1 fr1 m1 t1 c2 rs2 fr2 m2 ->
- exec_instrs f sp parent c2 rs2 fr2 m2 t2 c3 rs3 fr3 m3 ->
- t3 = t1 ** t2 ->
- exec_instrs f sp parent c1 rs1 fr1 m1 t3 c3 rs3 fr3 m3
-
-with exec_function_body:
- function -> frame -> val -> val ->
- regset -> mem -> trace -> regset -> mem -> Prop :=
- | exec_funct_body:
- forall f parent link ra rs m t rs' m1 m2 stk fr1 fr2 fr3 c,
- Mem.alloc m 0 f.(fn_stacksize) = (m1, stk) ->
- set_slot (init_frame f) Tint 0 link fr1 ->
- set_slot fr1 Tint 12 ra fr2 ->
- exec_instrs f (Vptr stk (Int.repr (-f.(fn_framesize)))) parent
- f.(fn_code) rs fr2 m1
- t (Mreturn :: c) rs' fr3 m2 ->
- exec_function_body f parent link ra rs m t rs' (Mem.free m2 stk)
-
-with exec_function:
- fundef -> frame -> regset -> mem -> trace -> regset -> mem -> Prop :=
- | exec_funct_internal:
- forall f parent rs m t rs' m',
- (forall link ra,
- Val.has_type link Tint ->
- Val.has_type ra Tint ->
- exec_function_body f parent link ra rs m t rs' m') ->
- exec_function (Internal f) parent rs m t rs' m'
- | exec_funct_external:
- forall ef parent args res rs1 rs2 m t,
+ forall s f sp cond args lbl c rs fr m,
+ eval_condition cond rs##args m = Some false ->
+ step (State s f sp (Mcond cond args lbl :: c) rs fr m)
+ E0 (State s f sp c rs fr m)
+ | exec_Mreturn:
+ forall s f stk soff c rs fr m,
+ step (State s f (Vptr stk soff) (Mreturn :: c) rs fr m)
+ E0 (Returnstate s rs (Mem.free m stk))
+ | exec_function_internal:
+ forall s f rs m m' stk,
+ Mem.alloc m 0 f.(fn_stacksize) = (m', stk) ->
+ step (Callstate s (Internal f) rs m)
+ E0 (State s f (Vptr stk (Int.repr (-f.(fn_framesize))))
+ f.(fn_code) rs (init_frame f) m')
+ | exec_function_external:
+ forall s ef args res rs1 rs2 m t,
event_match ef args t res ->
- extcall_arguments rs1 parent ef.(ef_sig) args ->
+ extcall_arguments rs1 (parent_frame s) ef.(ef_sig) args ->
rs2 = (rs1#(Conventions.loc_result ef.(ef_sig)) <- res) ->
- exec_function (External ef) parent rs1 m t rs2 m.
-
-Scheme exec_instr_ind4 := Minimality for exec_instr Sort Prop
- with exec_instrs_ind4 := Minimality for exec_instrs Sort Prop
- with exec_function_body_ind4 := Minimality for exec_function_body Sort Prop
- with exec_function_ind4 := Minimality for exec_function Sort Prop.
-
-(** Ugly mutual induction principle over evaluation derivations.
- Coq is not able to generate it directly, even though it is
- an immediate consequence of the 4 induction principles generated
- by the [Scheme] command above. *)
-
-Lemma exec_mutual_induction:
- forall
- (P
- P0 : function ->
- val ->
- frame ->
- code ->
- regset ->
- frame ->
- mem -> trace -> code -> regset -> frame -> mem -> Prop)
- (P1 : function ->
- frame ->
- val -> val -> regset -> mem -> trace -> regset -> mem -> Prop)
- (P2 : fundef ->
- frame -> regset -> mem -> trace -> regset -> mem -> Prop),
- (forall (f : function) (sp : val) (parent : frame) (lbl : label)
- (c : list instruction) (rs : regset) (fr : frame) (m : mem),
- P f sp parent (Mlabel lbl :: c) rs fr m E0 c rs fr m) ->
- (forall (f0 : function) (sp : val) (parent : frame) (ofs : int)
- (ty : typ) (dst : mreg) (c : list instruction) (rs : regset)
- (fr : frame) (m : mem) (v : val),
- get_slot fr ty (Int.signed ofs) v ->
- P f0 sp parent (Mgetstack ofs ty dst :: c) rs fr m E0 c rs # dst <- v
- fr m) ->
- (forall (f1 : function) (sp : val) (parent : frame) (src : mreg)
- (ofs : int) (ty : typ) (c : list instruction) (rs : mreg -> val)
- (fr : frame) (m : mem) (fr' : frame),
- set_slot fr ty (Int.signed ofs) (rs src) fr' ->
- P f1 sp parent (Msetstack src ofs ty :: c) rs fr m E0 c rs fr' m) ->
- (forall (f2 : function) (sp : val) (parent : frame) (ofs : int)
- (ty : typ) (dst : mreg) (c : list instruction) (rs : regset)
- (fr : frame) (m : mem) (v : val),
- get_slot parent ty (Int.signed ofs) v ->
- P f2 sp parent (Mgetparam ofs ty dst :: c) rs fr m E0 c rs # dst <- v
- fr m) ->
- (forall (f3 : function) (sp : val) (parent : frame) (op : operation)
- (args : list mreg) (res : mreg) (c : list instruction)
- (rs : mreg -> val) (fr : frame) (m : mem) (v : val),
- eval_operation ge sp op rs ## args = Some v ->
- P f3 sp parent (Mop op args res :: c) rs fr m E0 c rs # res <- v fr m) ->
- (forall (f4 : function) (sp : val) (parent : frame)
- (chunk : memory_chunk) (addr : addressing) (args : list mreg)
- (dst : mreg) (c : list instruction) (rs : mreg -> val) (fr : frame)
- (m : mem) (a v : val),
- eval_addressing ge sp addr rs ## args = Some a ->
- loadv chunk m a = Some v ->
- P f4 sp parent (Mload chunk addr args dst :: c) rs fr m E0 c
- rs # dst <- v fr m) ->
- (forall (f5 : function) (sp : val) (parent : frame)
- (chunk : memory_chunk) (addr : addressing) (args : list mreg)
- (src : mreg) (c : list instruction) (rs : mreg -> val) (fr : frame)
- (m m' : mem) (a : val),
- eval_addressing ge sp addr rs ## args = Some a ->
- storev chunk m a (rs src) = Some m' ->
- P f5 sp parent (Mstore chunk addr args src :: c) rs fr m E0 c rs fr
- m') ->
- (forall (f6 : function) (sp : val) (parent : frame) (sig : signature)
- (ros : mreg + ident) (c : list instruction) (rs : regset)
- (fr : frame) (m : mem) (t : trace) (f' : fundef) (rs' : regset)
- (m' : mem),
- find_function ge ros rs = Some f' ->
- exec_function f' fr rs m t rs' m' ->
- P2 f' fr rs m t rs' m' ->
- P f6 sp parent (Mcall sig ros :: c) rs fr m t c rs' fr m') ->
- (forall (f7 : function) (sp : val) (parent : frame)
- (c : list instruction) (rs : mreg -> val) (fr : frame) (m : mem)
- (sz : int) (m' : mem) (blk : block),
- rs Conventions.loc_alloc_argument = Vint sz ->
- alloc m 0 (Int.signed sz) = (m', blk) ->
- P f7 sp parent (Malloc :: c) rs fr m E0 c
- rs # Conventions.loc_alloc_result <- (Vptr blk Int.zero) fr m') ->
- (forall (f7 : function) (sp : val) (parent : frame) (lbl : label)
- (c : list instruction) (rs : regset) (fr : frame) (m : mem)
- (c' : code),
- find_label lbl (fn_code f7) = Some c' ->
- P f7 sp parent (Mgoto lbl :: c) rs fr m E0 c' rs fr m) ->
- (forall (f8 : function) (sp : val) (parent : frame) (cond : condition)
- (args : list mreg) (lbl : label) (c : list instruction)
- (rs : mreg -> val) (fr : frame) (m : mem) (c' : code),
- eval_condition cond rs ## args = Some true ->
- find_label lbl (fn_code f8) = Some c' ->
- P f8 sp parent (Mcond cond args lbl :: c) rs fr m E0 c' rs fr m) ->
- (forall (f9 : function) (sp : val) (parent : frame) (cond : condition)
- (args : list mreg) (lbl : label) (c : list instruction)
- (rs : mreg -> val) (fr : frame) (m : mem),
- eval_condition cond rs ## args = Some false ->
- P f9 sp parent (Mcond cond args lbl :: c) rs fr m E0 c rs fr m) ->
- (forall (f10 : function) (sp : val) (parent : frame) (c : code)
- (rs : regset) (fr : frame) (m : mem),
- P0 f10 sp parent c rs fr m E0 c rs fr m) ->
- (forall (f11 : function) (sp : val) (parent : frame) (c : code)
- (rs : regset) (fr : frame) (m : mem) (t : trace) (c' : code)
- (rs' : regset) (fr' : frame) (m' : mem),
- exec_instr f11 sp parent c rs fr m t c' rs' fr' m' ->
- P f11 sp parent c rs fr m t c' rs' fr' m' ->
- P0 f11 sp parent c rs fr m t c' rs' fr' m') ->
- (forall (f12 : function) (sp : val) (parent : frame) (c1 : code)
- (rs1 : regset) (fr1 : frame) (m1 : mem) (t1 : trace) (c2 : code)
- (rs2 : regset) (fr2 : frame) (m2 : mem) (t2 : trace) (c3 : code)
- (rs3 : regset) (fr3 : frame) (m3 : mem) (t3 : trace),
- exec_instrs f12 sp parent c1 rs1 fr1 m1 t1 c2 rs2 fr2 m2 ->
- P0 f12 sp parent c1 rs1 fr1 m1 t1 c2 rs2 fr2 m2 ->
- exec_instrs f12 sp parent c2 rs2 fr2 m2 t2 c3 rs3 fr3 m3 ->
- P0 f12 sp parent c2 rs2 fr2 m2 t2 c3 rs3 fr3 m3 ->
- t3 = t1 ** t2 -> P0 f12 sp parent c1 rs1 fr1 m1 t3 c3 rs3 fr3 m3) ->
- (forall (f13 : function) (parent : frame) (link ra : val)
- (rs : regset) (m : mem) (t : trace) (rs' : regset) (m1 m2 : mem)
- (stk : block) (fr1 fr2 fr3 : frame) (c : list instruction),
- alloc m 0 (fn_stacksize f13) = (m1, stk) ->
- set_slot (init_frame f13) Tint 0 link fr1 ->
- set_slot fr1 Tint 12 ra fr2 ->
- exec_instrs f13 (Vptr stk (Int.repr (- fn_framesize f13))) parent
- (fn_code f13) rs fr2 m1 t (Mreturn :: c) rs' fr3 m2 ->
- P0 f13 (Vptr stk (Int.repr (- fn_framesize f13))) parent
- (fn_code f13) rs fr2 m1 t (Mreturn :: c) rs' fr3 m2 ->
- P1 f13 parent link ra rs m t rs' (free m2 stk)) ->
- (forall (f14 : function) (parent : frame) (rs : regset) (m : mem)
- (t : trace) (rs' : regset) (m' : mem),
- (forall link ra : val,
- Val.has_type link Tint ->
- Val.has_type ra Tint ->
- exec_function_body f14 parent link ra rs m t rs' m') ->
- (forall link ra : val,
- Val.has_type link Tint ->
- Val.has_type ra Tint -> P1 f14 parent link ra rs m t rs' m') ->
- P2 (Internal f14) parent rs m t rs' m') ->
- (forall (ef : external_function) (parent : frame) (args : list val)
- (res : val) (rs1 : mreg -> val) (rs2 : RegEq.t -> val) (m : mem)
- (t0 : trace),
- event_match ef args t0 res ->
- extcall_arguments rs1 parent ef.(ef_sig) args ->
- rs2 = rs1 # (Conventions.loc_result (ef_sig ef)) <- res ->
- P2 (External ef) parent rs1 m t0 rs2 m) ->
- (forall (f16 : function) (v : val) (f17 : frame) (c : code)
- (r : regset) (f18 : frame) (m : mem) (t : trace) (c0 : code)
- (r0 : regset) (f19 : frame) (m0 : mem),
- exec_instr f16 v f17 c r f18 m t c0 r0 f19 m0 ->
- P f16 v f17 c r f18 m t c0 r0 f19 m0)
- /\ (forall (f16 : function) (v : val) (f17 : frame) (c : code)
- (r : regset) (f18 : frame) (m : mem) (t : trace) (c0 : code)
- (r0 : regset) (f19 : frame) (m0 : mem),
- exec_instrs f16 v f17 c r f18 m t c0 r0 f19 m0 ->
- P0 f16 v f17 c r f18 m t c0 r0 f19 m0)
- /\ (forall (f16 : function) (f17 : frame) (v v0 : val) (r : regset)
- (m : mem) (t : trace) (r0 : regset) (m0 : mem),
- exec_function_body f16 f17 v v0 r m t r0 m0 ->
- P1 f16 f17 v v0 r m t r0 m0)
- /\ (forall (f16 : fundef) (f17 : frame) (r : regset) (m : mem) (t : trace)
- (r0 : regset) (m0 : mem),
- exec_function f16 f17 r m t r0 m0 -> P2 f16 f17 r m t r0 m0).
-Proof.
- intros. split. apply (exec_instr_ind4 P P0 P1 P2); assumption.
- split. apply (exec_instrs_ind4 P P0 P1 P2); assumption.
- split. apply (exec_function_body_ind4 P P0 P1 P2); assumption.
- apply (exec_function_ind4 P P0 P1 P2); assumption.
-Qed.
+ step (Callstate s (External ef) rs1 m)
+ t (Returnstate s rs2 m)
+ | exec_return:
+ forall f sp c fr s rs m,
+ step (Returnstate (Stackframe f sp c fr :: s) rs m)
+ E0 (State s f sp c rs fr m).
End RELSEM.
-Definition exec_program (p: program) (t: trace) (r: val) : Prop :=
- let ge := Genv.globalenv p in
- let m0 := Genv.init_mem p in
- exists b, exists f, exists rs, exists m,
- Genv.find_symbol ge p.(prog_main) = Some b /\
- Genv.find_funct_ptr ge b = Some f /\
- exec_function ge f empty_frame (Regmap.init Vundef) m0 t rs m /\
- rs R3 = r.
+Inductive initial_state (p: program): state -> Prop :=
+ | initial_state_intro: forall b f,
+ let ge := Genv.globalenv p in
+ let m0 := Genv.init_mem p in
+ Genv.find_symbol ge p.(prog_main) = Some b ->
+ Genv.find_funct_ptr ge b = Some f ->
+ initial_state p (Callstate nil f (Regmap.init Vundef) m0).
+
+Inductive final_state: state -> int -> Prop :=
+ | final_state_intro: forall rs m r,
+ rs R3 = Vint r ->
+ final_state (Returnstate nil rs m) r.
+Definition exec_program (p: program) (beh: program_behavior) : Prop :=
+ program_behaves step (initial_state p) final_state (Genv.globalenv p) beh.
diff --git a/backend/Machabstr2concr.v b/backend/Machabstr2concr.v
new file mode 100644
index 0000000..5349fb5
--- /dev/null
+++ b/backend/Machabstr2concr.v
@@ -0,0 +1,947 @@
+(** Simulation between the two semantics for the Mach language. *)
+
+Require Import Coqlib.
+Require Import Maps.
+Require Import AST.
+Require Import Integers.
+Require Import Values.
+Require Import Mem.
+Require Import Events.
+Require Import Globalenvs.
+Require Import Smallstep.
+Require Import Op.
+Require Import Locations.
+Require Import Mach.
+Require Import Machtyping.
+Require Import Machabstr.
+Require Import Machconcr.
+Require Import Stackingproof.
+Require Import PPCgenretaddr.
+
+(** Two semantics were defined for the Mach intermediate language:
+- The concrete semantics (file [Mach]), where the whole activation
+ record resides in memory and the [Mgetstack], [Msetstack] and
+ [Mgetparent] are interpreted as [sp]-relative memory accesses.
+- The abstract semantics (file [Machabstr]), where the activation
+ record is split in two parts: the Cminor stack data, resident in
+ memory, and the frame information, residing not in memory but
+ in additional evaluation environments.
+
+ In this file, we show a simulation result between these
+ semantics: if a program executes with some behaviour [beh] in the
+ abstract semantics, it also executes with the same behaviour in
+ the concrete semantics. This result bridges the correctness proof
+ in file [Stackingproof] (which uses the abstract Mach semantics
+ as output) and that in file [PPCgenproof] (which uses the concrete
+ Mach semantics as input).
+*)
+
+Remark align_16_top_ge:
+ forall lo hi,
+ hi <= align_16_top lo hi.
+Proof.
+ intros. unfold align_16_top. apply Zmax_bound_r.
+ assert (forall x, x <= (x + 15) / 16 * 16).
+ intro. assert (16 > 0). omega.
+ generalize (Z_div_mod_eq (x + 15) 16 H). intro.
+ replace ((x + 15) / 16 * 16) with ((x + 15) - (x + 15) mod 16).
+ generalize (Z_mod_lt (x + 15) 16 H). omega.
+ rewrite Zmult_comm. omega.
+ generalize (H (hi - lo)). omega.
+Qed.
+
+Remark align_16_top_pos:
+ forall lo hi,
+ 0 <= align_16_top lo hi.
+Proof.
+ intros. unfold align_16_top. apply Zmax_bound_l. omega.
+Qed.
+
+Remark size_type_chunk:
+ forall ty, size_chunk (chunk_of_type ty) = AST.typesize ty.
+Proof.
+ destruct ty; reflexivity.
+Qed.
+
+(** * Agreement between frames and memory-resident activation records *)
+
+(** ** Agreement for one frame *)
+
+(** The core idea of the simulation proof is that for all active
+ functions, the memory-allocated activation record, in the concrete
+ semantics, contains the same data as the Cminor stack block
+ (at positive offsets) and the frame of the function (at negative
+ offsets) in the abstract semantics.
+
+ This intuition (activation record = Cminor stack data + frame)
+ is formalized by the following predicate [frame_match fr sp base mm ms].
+ [fr] is a frame and [mm] the current memory state in the abstract
+ semantics. [ms] is the current memory state in the concrete semantics.
+ The stack pointer is [Vptr sp base] in both semantics. *)
+
+Inductive frame_match (fr: frame) (sp: block) (base: int)
+ (mm ms: mem) : Prop :=
+ frame_match_intro:
+ valid_block ms sp ->
+ low_bound mm sp = 0 ->
+ low_bound ms sp = fr.(fr_low) ->
+ high_bound ms sp >= 0 ->
+ fr.(fr_low) <= -24 ->
+ Int.min_signed <= fr.(fr_low) ->
+ base = Int.repr fr.(fr_low) ->
+ (forall ty ofs,
+ fr.(fr_low) + 24 <= ofs -> ofs + AST.typesize ty <= 0 ->
+ load (chunk_of_type ty) ms sp ofs = Some(fr.(fr_contents) ty ofs)) ->
+ frame_match fr sp base mm ms.
+
+(** The following two innocuous-looking lemmas are the key results
+ showing that [sp]-relative memory accesses in the concrete
+ semantics behave like the direct frame accesses in the abstract
+ semantics. First, a value [v] that has type [ty] is preserved
+ when stored in memory with chunk [chunk_of_type ty], then read
+ back with the same chunk. The typing hypothesis is crucial here:
+ for instance, a float value reads back as [Vundef] when stored
+ and load with chunk [Mint32]. *)
+
+Lemma load_result_ty:
+ forall v ty,
+ Val.has_type v ty -> Val.load_result (chunk_of_type ty) v = v.
+Proof.
+ destruct v; destruct ty; simpl; contradiction || reflexivity.
+Qed.
+
+(** Second, computations of [sp]-relative offsets using machine
+ arithmetic (as done in the concrete semantics) never overflows
+ and behaves identically to the offset computations using exact
+ arithmetic (as done in the abstract semantics). *)
+
+Lemma int_add_no_overflow:
+ forall x y,
+ Int.min_signed <= Int.signed x + Int.signed y <= Int.max_signed ->
+ Int.signed (Int.add x y) = Int.signed x + Int.signed y.
+Proof.
+ intros. rewrite Int.add_signed. rewrite Int.signed_repr. auto. auto.
+Qed.
+
+(** Given matching frames and activation records, loading from the
+ activation record (in the concrete semantics) behaves identically
+ to reading the corresponding slot from the frame
+ (in the abstract semantics). *)
+
+Lemma frame_match_get_slot:
+ forall fr sp base mm ms ty ofs v,
+ frame_match fr sp base mm ms ->
+ get_slot fr ty (Int.signed ofs) v ->
+ load_stack ms (Vptr sp base) ty ofs = Some v.
+Proof.
+ intros. inv H. inv H0.
+ unfold load_stack, Val.add, loadv.
+ assert (Int.signed (Int.repr (fr_low fr)) = fr_low fr).
+ apply Int.signed_repr.
+ split. auto. apply Zle_trans with (-24). auto. compute; congruence.
+ assert (Int.signed (Int.add (Int.repr (fr_low fr)) ofs) = fr_low fr + Int.signed ofs).
+ rewrite int_add_no_overflow. rewrite H0. auto.
+ rewrite H0. split. omega. apply Zle_trans with 0.
+ generalize (AST.typesize_pos ty). omega. compute; congruence.
+ rewrite H9. apply H8. omega. auto.
+Qed.
+
+(** Assigning a value to a frame slot (in the abstract semantics)
+ corresponds to storing this value in the activation record
+ (in the concrete semantics). Moreover, agreement between frames
+ and activation records is preserved. *)
+
+Lemma frame_match_set_slot:
+ forall fr sp base mm ms ty ofs v fr',
+ frame_match fr sp base mm ms ->
+ set_slot fr ty (Int.signed ofs) v fr' ->
+ Val.has_type v ty ->
+ Mem.extends mm ms ->
+ exists ms',
+ store_stack ms (Vptr sp base) ty ofs v = Some ms' /\
+ frame_match fr' sp base mm ms' /\
+ Mem.extends mm ms' /\
+ Int.signed base + 24 <= Int.signed (Int.add base ofs).
+Proof.
+ intros. inv H. inv H0.
+ unfold store_stack, Val.add, storev.
+ assert (Int.signed (Int.repr (fr_low fr)) = fr_low fr).
+ apply Int.signed_repr.
+ split. auto. apply Zle_trans with (-24). auto. compute; congruence.
+ assert (Int.signed (Int.add (Int.repr (fr_low fr)) ofs) = fr_low fr + Int.signed ofs).
+ rewrite int_add_no_overflow. congruence.
+ rewrite H0. split. omega. apply Zle_trans with 0.
+ generalize (AST.typesize_pos ty). omega. compute; congruence.
+ rewrite H11.
+ assert (exists ms', store (chunk_of_type ty) ms sp (fr_low fr + Int.signed ofs) v = Some ms').
+ apply valid_access_store.
+ constructor. auto. omega.
+ rewrite size_type_chunk. omega.
+ destruct H12 as [ms' STORE].
+ generalize (low_bound_store _ _ _ _ _ _ STORE sp). intro LB.
+ generalize (high_bound_store _ _ _ _ _ _ STORE sp). intro HB.
+ exists ms'.
+ split. exact STORE.
+ (* frame match *)
+ split. constructor; simpl fr_low; try congruence.
+ eauto with mem. intros. simpl.
+ destruct (zeq (fr_low fr + Int.signed ofs) ofs0). subst ofs0.
+ destruct (typ_eq ty ty0). subst ty0.
+ (* same *)
+ transitivity (Some (Val.load_result (chunk_of_type ty) v)).
+ eapply load_store_same; eauto.
+ decEq. apply load_result_ty; auto.
+ (* mismatch *)
+ eapply load_store_mismatch'; eauto with mem.
+ destruct ty; destruct ty0; simpl; congruence.
+ destruct (zle (ofs0 + AST.typesize ty0) (fr_low fr + Int.signed ofs)).
+ (* disjoint *)
+ rewrite <- H10; auto. eapply load_store_other; eauto.
+ right; left. rewrite size_type_chunk; auto.
+ destruct (zle (fr_low fr + Int.signed ofs + AST.typesize ty)).
+ rewrite <- H10; auto. eapply load_store_other; eauto.
+ right; right. rewrite size_type_chunk; auto.
+ (* overlap *)
+ eapply load_store_overlap'; eauto with mem.
+ rewrite size_type_chunk; auto.
+ rewrite size_type_chunk; auto.
+ (* extends *)
+ split. eapply store_outside_extends; eauto.
+ left. rewrite size_type_chunk. omega.
+ (* bound *)
+ omega.
+Qed.
+
+(** Agreement is preserved by stores within blocks other than the
+ one pointed to by [sp], or to the low 24 bytes
+ of the [sp] block. *)
+
+Lemma frame_match_store_other:
+ forall fr sp base mm ms chunk b ofs v ms',
+ frame_match fr sp base mm ms ->
+ store chunk ms b ofs v = Some ms' ->
+ sp <> b \/ ofs + size_chunk chunk <= fr_low fr + 24 ->
+ frame_match fr sp base mm ms'.
+Proof.
+ intros. inv H.
+ generalize (low_bound_store _ _ _ _ _ _ H0 sp). intro LB.
+ generalize (high_bound_store _ _ _ _ _ _ H0 sp). intro HB.
+ apply frame_match_intro; auto.
+ eauto with mem.
+ congruence.
+ congruence.
+ intros. rewrite <- H9; auto.
+ eapply load_store_other; eauto.
+ elim H1; intro. auto. right. rewrite size_type_chunk. omega.
+Qed.
+
+Lemma frame_match_store:
+ forall fr sp base mm ms chunk b ofs v mm' ms',
+ frame_match fr sp base mm ms ->
+ store chunk mm b ofs v = Some mm' ->
+ store chunk ms b ofs v = Some ms' ->
+ frame_match fr sp base mm' ms'.
+Proof.
+ intros. inv H.
+ generalize (low_bound_store _ _ _ _ _ _ H0 sp). intro LBm.
+ generalize (low_bound_store _ _ _ _ _ _ H1 sp). intro LBs.
+ generalize (high_bound_store _ _ _ _ _ _ H0 sp). intro HBm.
+ generalize (high_bound_store _ _ _ _ _ _ H1 sp). intro HBs.
+ apply frame_match_intro; auto.
+ eauto with mem.
+ congruence. congruence. congruence.
+ intros. rewrite <- H9; auto. eapply load_store_other; eauto.
+ destruct (zeq sp b). subst b. right.
+ rewrite size_type_chunk.
+ assert (valid_access mm chunk sp ofs) by eauto with mem.
+ inv H10. left. omega.
+ auto.
+Qed.
+
+(** The low 24 bytes of a frame are preserved by a parallel
+ store in the two memory states. *)
+
+Lemma frame_match_store_link_invariant:
+ forall fr sp base mm ms chunk b ofs v mm' ms' ofs',
+ frame_match fr sp base mm ms ->
+ store chunk mm b ofs v = Some mm' ->
+ store chunk ms b ofs v = Some ms' ->
+ ofs' <= fr_low fr + 20 ->
+ load Mint32 ms' sp ofs' = load Mint32 ms sp ofs'.
+Proof.
+ intros. inv H.
+ eapply load_store_other; eauto.
+ destruct (eq_block sp b). subst b.
+ right; left. change (size_chunk Mint32) with 4.
+ assert (valid_access mm chunk sp ofs) by eauto with mem.
+ inv H. omega.
+ auto.
+Qed.
+
+(** Memory allocation of the Cminor stack data block (in the abstract
+ semantics) and of the whole activation record (in the concrete
+ semantics) return memory states that agree according to [frame_match].
+ Moreover, [frame_match] relations over already allocated blocks
+ remain true. *)
+
+Lemma frame_match_new:
+ forall mm ms mm' ms' sp sp' f,
+ mm.(nextblock) = ms.(nextblock) ->
+ alloc mm 0 f.(fn_stacksize) = (mm', sp) ->
+ alloc ms (- f.(fn_framesize)) (align_16_top (- f.(fn_framesize)) f.(fn_stacksize)) = (ms', sp') ->
+ f.(fn_framesize) >= 24 ->
+ f.(fn_framesize) <= -Int.min_signed ->
+ sp = sp' /\
+ frame_match (init_frame f) sp (Int.repr (-f.(fn_framesize))) mm' ms'.
+Proof.
+ intros.
+ assert (sp = sp').
+ exploit alloc_result. eexact H0. exploit alloc_result. eexact H1.
+ congruence.
+ subst sp'. split. auto.
+ generalize (low_bound_alloc_same _ _ _ _ _ H0). intro LBm.
+ generalize (low_bound_alloc_same _ _ _ _ _ H1). intro LBs.
+ generalize (high_bound_alloc_same _ _ _ _ _ H0). intro HBm.
+ generalize (high_bound_alloc_same _ _ _ _ _ H1). intro HBs.
+ constructor; simpl; eauto with mem.
+ rewrite HBs. apply Zle_ge. apply align_16_top_pos.
+ omega. omega.
+ intros.
+ eapply load_alloc_same'; eauto. omega.
+ rewrite size_type_chunk. apply Zle_trans with 0. auto.
+ apply align_16_top_pos.
+Qed.
+
+Lemma frame_match_alloc:
+ forall mm ms fr sp base lom him los his mm' ms' bm bs,
+ mm.(nextblock) = ms.(nextblock) ->
+ frame_match fr sp base mm ms ->
+ alloc mm lom him = (mm', bm) ->
+ alloc ms los his = (ms', bs) ->
+ frame_match fr sp base mm' ms'.
+Proof.
+ intros. inversion H0.
+ assert (valid_block mm sp). red. rewrite H. auto.
+ exploit low_bound_alloc_other. eexact H1. eexact H11. intro LBm.
+ exploit high_bound_alloc_other. eexact H1. eexact H11. intro HBm.
+ exploit low_bound_alloc_other. eexact H2. eexact H3. intro LBs.
+ exploit high_bound_alloc_other. eexact H2. eexact H3. intro HBs.
+ apply frame_match_intro.
+ eapply valid_block_alloc; eauto.
+ congruence. congruence. congruence. auto. auto. auto.
+ intros. eapply load_alloc_other; eauto.
+Qed.
+
+(** [frame_match] relations are preserved by freeing a block
+ other than the one pointed to by [sp]. *)
+
+Lemma frame_match_free:
+ forall fr sp base mm ms b,
+ frame_match fr sp base mm ms ->
+ sp <> b ->
+ frame_match fr sp base (free mm b) (free ms b).
+Proof.
+ intros. inversion H.
+ generalize (low_bound_free mm _ _ H0); intro LBm.
+ generalize (low_bound_free ms _ _ H0); intro LBs.
+ generalize (high_bound_free mm _ _ H0); intro HBm.
+ generalize (high_bound_free ms _ _ H0); intro HBs.
+ apply frame_match_intro; auto.
+ congruence. congruence. congruence.
+ intros. rewrite <- H8; auto. apply load_free. auto.
+Qed.
+
+(** ** Invariant for stacks *)
+
+Section SIMULATION.
+
+Variable p: program.
+Let ge := Genv.globalenv p.
+
+(** The [match_stacks] predicate relates a Machabstr call stack
+ with the corresponding Machconcr stack. In addition to enforcing
+ the [frame_match] predicate for each stack frame, we also enforce:
+- Proper chaining of activation record on the Machconcr side.
+- Preservation of the return address stored at the bottom of the
+ activation record.
+- Separation between the memory blocks holding the activation records:
+ their addresses increase strictly from caller to callee.
+*)
+
+Inductive match_stacks:
+ list Machabstr.stackframe -> list Machconcr.stackframe ->
+ block -> int -> mem -> mem -> Prop :=
+ | match_stacks_nil: forall sp base mm ms,
+ load Mint32 ms sp (Int.signed base) = Some (Vptr Mem.nullptr Int.zero) ->
+ load Mint32 ms sp (Int.signed base + 12) = Some Vzero ->
+ match_stacks nil nil sp base mm ms
+ | match_stacks_cons: forall f sp' base' c fr s fb ra ts sp base mm ms,
+ frame_match fr sp' base' mm ms ->
+ sp' < sp ->
+ load Mint32 ms sp (Int.signed base) = Some (Vptr sp' base') ->
+ load Mint32 ms sp (Int.signed base + 12) = Some ra ->
+ Genv.find_funct_ptr ge fb = Some (Internal f) ->
+ match_stacks s ts sp' base' mm ms ->
+ match_stacks (Machabstr.Stackframe f (Vptr sp' base') c fr :: s)
+ (Machconcr.Stackframe fb (Vptr sp' base') ra c :: ts)
+ sp base mm ms.
+
+Remark frame_match_base_eq:
+ forall fr sp base mm ms,
+ frame_match fr sp base mm ms -> Int.signed base = fr_low fr.
+Proof.
+ intros. inv H. apply Int.signed_repr. split; auto.
+ apply Zle_trans with (-24); auto. compute; congruence.
+Qed.
+
+(** If [match_stacks] holds, a lookup in the parent frame in the
+ Machabstr semantics corresponds to two memory loads in the
+ Machconcr semantics, one to load the pointer to the parent's
+ activation record, the second to read within this record. *)
+
+Lemma match_stacks_get_parent:
+ forall s ts sp base mm ms ty ofs v,
+ match_stacks s ts sp base mm ms ->
+ get_slot (parent_frame s) ty (Int.signed ofs) v ->
+ exists parent,
+ load_stack ms (Vptr sp base) Tint (Int.repr 0) = Some parent
+ /\ load_stack ms parent ty ofs = Some v.
+Proof.
+ intros. inv H; simpl in H0.
+ inv H0. simpl in H3. elimtype False. generalize (AST.typesize_pos ty). omega.
+ exists (Vptr sp' base'); split.
+ unfold load_stack. simpl. rewrite Int.add_zero. auto.
+ eapply frame_match_get_slot; eauto.
+Qed.
+
+(** If [match_stacks] holds, reading memory at offsets 0 and 12
+ from the stack pointer returns the stack pointer and return
+ address of the caller, respectively. *)
+
+Lemma match_stacks_load_links:
+ forall fr s ts sp base mm ms,
+ frame_match fr sp base mm ms ->
+ match_stacks s ts sp base mm ms ->
+ load_stack ms (Vptr sp base) Tint (Int.repr 0) = Some (parent_sp ts) /\
+ load_stack ms (Vptr sp base) Tint (Int.repr 12) = Some (parent_ra ts).
+Proof.
+ intros. unfold load_stack. simpl. rewrite Int.add_zero.
+ replace (Int.signed (Int.add base (Int.repr 12)))
+ with (Int.signed base + 12).
+ inv H0; simpl; auto.
+ inv H. rewrite Int.add_signed.
+ change (Int.signed (Int.repr 12)) with 12.
+ repeat rewrite Int.signed_repr. auto.
+ split. omega. apply Zle_trans with (-12). omega. compute; congruence.
+ split. auto. apply Zle_trans with (-24). auto. compute; congruence.
+Qed.
+
+(** The [match_stacks] invariant is preserved by memory stores
+ outside the 24-byte reserved area at the bottom of activation records.
+*)
+
+Lemma match_stacks_store_other:
+ forall s ts sp base ms mm,
+ match_stacks s ts sp base mm ms ->
+ forall chunk b ofs v ms',
+ store chunk ms b ofs v = Some ms' ->
+ sp < b ->
+ match_stacks s ts sp base mm ms'.
+Proof.
+ induction 1; intros.
+ assert (sp <> b). unfold block; omega.
+ constructor.
+ rewrite <- H. eapply load_store_other; eauto.
+ rewrite <- H0. eapply load_store_other; eauto.
+ assert (sp <> b). unfold block; omega.
+ econstructor; eauto.
+ eapply frame_match_store_other; eauto.
+ left. unfold block; omega.
+ rewrite <- H1. eapply load_store_other; eauto.
+ rewrite <- H2. eapply load_store_other; eauto.
+ eapply IHmatch_stacks; eauto. omega.
+Qed.
+
+Lemma match_stacks_store_slot:
+ forall s ts sp base ms mm,
+ match_stacks s ts sp base mm ms ->
+ forall ty ofs v ms',
+ store_stack ms (Vptr sp base) ty ofs v = Some ms' ->
+ Int.signed base + 24 <= Int.signed (Int.add base ofs) ->
+ match_stacks s ts sp base mm ms'.
+Proof.
+ intros.
+ unfold store_stack in H0. simpl in H0.
+ assert (load Mint32 ms' sp (Int.signed base) = load Mint32 ms sp (Int.signed base)).
+ eapply load_store_other; eauto.
+ right; left. change (size_chunk Mint32) with 4; omega.
+ assert (load Mint32 ms' sp (Int.signed base + 12) = load Mint32 ms sp (Int.signed base + 12)).
+ eapply load_store_other; eauto.
+ right; left. change (size_chunk Mint32) with 4; omega.
+ inv H.
+ constructor; congruence.
+ constructor; auto.
+ eapply frame_match_store_other; eauto.
+ left; unfold block; omega.
+ congruence. congruence.
+ eapply match_stacks_store_other; eauto.
+Qed.
+
+Lemma match_stacks_store:
+ forall s ts sp base ms mm,
+ match_stacks s ts sp base mm ms ->
+ forall fr chunk b ofs v mm' ms',
+ frame_match fr sp base mm ms ->
+ store chunk mm b ofs v = Some mm' ->
+ store chunk ms b ofs v = Some ms' ->
+ match_stacks s ts sp base mm' ms'.
+Proof.
+ induction 1; intros.
+ assert (Int.signed base = fr_low fr) by (eapply frame_match_base_eq; eauto).
+ constructor.
+ rewrite <- H. eapply frame_match_store_link_invariant; eauto. omega.
+ rewrite <- H0. eapply frame_match_store_link_invariant; eauto. omega.
+ assert (Int.signed base = fr_low fr0) by (eapply frame_match_base_eq; eauto).
+ econstructor; eauto.
+ eapply frame_match_store; eauto.
+ rewrite <- H1. eapply frame_match_store_link_invariant; eauto. omega.
+ rewrite <- H2. eapply frame_match_store_link_invariant; eauto. omega.
+Qed.
+
+Lemma match_stacks_alloc:
+ forall s ts sp base ms mm,
+ match_stacks s ts sp base mm ms ->
+ forall lom him mm' bm los his ms' bs,
+ mm.(nextblock) = ms.(nextblock) ->
+ alloc mm lom him = (mm', bm) ->
+ alloc ms los his = (ms', bs) ->
+ match_stacks s ts sp base mm' ms'.
+Proof.
+ induction 1; intros.
+ constructor.
+ rewrite <- H; eapply load_alloc_unchanged; eauto with mem.
+ rewrite <- H0; eapply load_alloc_unchanged; eauto with mem.
+ econstructor; eauto.
+ eapply frame_match_alloc; eauto.
+ rewrite <- H1; eapply load_alloc_unchanged; eauto with mem.
+ rewrite <- H2; eapply load_alloc_unchanged; eauto with mem.
+Qed.
+
+Lemma match_stacks_free:
+ forall s ts sp base ms mm,
+ match_stacks s ts sp base mm ms ->
+ forall b,
+ sp < b ->
+ match_stacks s ts sp base (Mem.free mm b) (Mem.free ms b).
+Proof.
+ induction 1; intros.
+ assert (sp <> b). unfold block; omega.
+ constructor.
+ rewrite <- H. apply load_free; auto.
+ rewrite <- H0. apply load_free; auto.
+ assert (sp <> b). unfold block; omega.
+ econstructor; eauto.
+ eapply frame_match_free; eauto. unfold block; omega.
+ rewrite <- H1. apply load_free; auto.
+ rewrite <- H2. apply load_free; auto.
+ eapply IHmatch_stacks; eauto. omega.
+Qed.
+
+(** Invocation of a function temporarily violates the [mach_stacks]
+ invariant: the return address and back link are not yet stored
+ in the appropriate parts of the activation record.
+ The following [match_stacks_partial] predicate is a weaker version
+ of [match_stacks] that captures this situation. *)
+
+Inductive match_stacks_partial:
+ list Machabstr.stackframe -> list Machconcr.stackframe ->
+ mem -> mem -> Prop :=
+ | match_stacks_partial_nil: forall mm ms,
+ match_stacks_partial nil nil mm ms
+ | match_stacks_partial_cons: forall f sp base c fr s fb ra ts mm ms,
+ frame_match fr sp base mm ms ->
+ sp < ms.(nextblock) ->
+ Genv.find_funct_ptr ge fb = Some (Internal f) ->
+ match_stacks s ts sp base mm ms ->
+ Val.has_type ra Tint ->
+ match_stacks_partial (Machabstr.Stackframe f (Vptr sp base) c fr :: s)
+ (Machconcr.Stackframe fb (Vptr sp base) ra c :: ts)
+ mm ms.
+
+Lemma match_stacks_match_stacks_partial:
+ forall s ts sp base mm ms,
+ match_stacks s ts sp base mm ms ->
+ match_stacks_partial s ts (free mm sp) (free ms sp).
+Proof.
+ intros. inv H. constructor.
+ econstructor.
+ eapply frame_match_free; eauto. unfold block; omega.
+ simpl. inv H0; auto.
+ auto.
+ apply match_stacks_free; auto.
+ generalize (Mem.load_inv _ _ _ _ _ H3). intros [A B].
+ rewrite B.
+ destruct (getN (pred_size_chunk Mint32) (Int.signed base + 12)
+ (contents (blocks ms sp))); exact I.
+Qed.
+
+Lemma match_stacks_function_entry:
+ forall s ts mm ms lom him mm' los his ms' stk ms'' ms''' base,
+ match_stacks_partial s ts mm ms ->
+ alloc mm lom him = (mm', stk) ->
+ alloc ms los his = (ms', stk) ->
+ store Mint32 ms' stk (Int.signed base) (parent_sp ts) = Some ms'' ->
+ store Mint32 ms'' stk (Int.signed base + 12) (parent_ra ts) = Some ms''' ->
+ match_stacks s ts stk base mm' ms'''.
+Proof.
+ intros.
+ assert (WT_SP: Val.has_type (parent_sp ts) Tint).
+ inv H; simpl; auto.
+ assert (WT_RA: Val.has_type (parent_ra ts) Tint).
+ inv H; simpl; auto.
+ assert (load Mint32 ms''' stk (Int.signed base) = Some (parent_sp ts)).
+ transitivity (load Mint32 ms'' stk (Int.signed base)).
+ eapply load_store_other; eauto. right; left. simpl. omega.
+ transitivity (Some (Val.load_result (chunk_of_type Tint) (parent_sp ts))).
+ simpl chunk_of_type. eapply load_store_same; eauto.
+ decEq. apply load_result_ty. auto.
+ assert (load Mint32 ms''' stk (Int.signed base + 12) = Some (parent_ra ts)).
+ transitivity (Some (Val.load_result (chunk_of_type Tint) (parent_ra ts))).
+ simpl chunk_of_type. eapply load_store_same; eauto.
+ decEq. apply load_result_ty. auto.
+ inv H; simpl in *.
+ constructor; auto.
+ assert (sp < stk). rewrite (alloc_result _ _ _ _ _ H1). auto.
+ assert (sp <> stk). unfold block; omega.
+ assert (nextblock mm = nextblock ms).
+ rewrite <- (alloc_result _ _ _ _ _ H0).
+ rewrite <- (alloc_result _ _ _ _ _ H1). auto.
+ econstructor; eauto.
+ eapply frame_match_store_other; eauto.
+ eapply frame_match_store_other; eauto.
+ eapply frame_match_alloc with (mm := mm) (ms := ms); eauto.
+ eapply match_stacks_store_other; eauto.
+ eapply match_stacks_store_other; eauto.
+ eapply match_stacks_alloc with (mm := mm) (ms := ms); eauto.
+ Qed.
+
+(** ** Invariant between states. *)
+
+(** The [match_state] predicate relates a Machabstr state with
+ a Machconcr state. In addition to [match_stacks] between the
+ stacks, we ask that
+- The Machabstr frame is properly stored in the activation record,
+ as characterized by [frame_match].
+- The Machconcr memory state extends the Machabstr memory state,
+ in the sense of the [Mem.extends] relation defined in module [Mem]. *)
+
+Inductive match_states:
+ Machabstr.state -> Machconcr.state -> Prop :=
+ | match_states_intro:
+ forall s f sp base c rs fr mm ts fb ms
+ (STACKS: match_stacks s ts sp base mm ms)
+ (FM: frame_match fr sp base mm ms)
+ (MEXT: Mem.extends mm ms)
+ (FIND: Genv.find_funct_ptr ge fb = Some (Internal f)),
+ match_states (Machabstr.State s f (Vptr sp base) c rs fr mm)
+ (Machconcr.State ts fb (Vptr sp base) c rs ms)
+ | match_states_call:
+ forall s f rs mm ts fb ms
+ (STACKS: match_stacks_partial s ts mm ms)
+ (MEXT: Mem.extends mm ms)
+ (FIND: Genv.find_funct_ptr ge fb = Some f),
+ match_states (Machabstr.Callstate s f rs mm)
+ (Machconcr.Callstate ts fb rs ms)
+ | match_states_return:
+ forall s rs mm ts ms
+ (STACKS: match_stacks_partial s ts mm ms)
+ (MEXT: Mem.extends mm ms),
+ match_states (Machabstr.Returnstate s rs mm)
+ (Machconcr.Returnstate ts rs ms).
+
+
+(** * The proof of simulation *)
+
+(** The proof of simulation relies on diagrams of the following form:
+<<
+ st1 --------------- st2
+ | |
+ t| |t
+ | |
+ v v
+ st1'--------------- st2'
+>>
+ The precondition is matching between the initial states [st1] and
+ [st2], as usual, plus the fact that [st1] is well-typed
+ in the sense of predicate [wt_state] from module [Machtyping].
+ The postcondition is matching between the final states [st1']
+ and [st2']. The well-typedness of [st2] is not part of the
+ postcondition, since it follows from that of [st1] if the
+ program is well-typed. (See the subject reduction property
+ in module [Machtyping].)
+*)
+
+Lemma find_function_find_function_ptr:
+ forall ros rs f',
+ find_function ge ros rs = Some f' ->
+ exists fb', Genv.find_funct_ptr ge fb' = Some f' /\ find_function_ptr ge ros rs = Some fb'.
+Proof.
+ intros until f'. destruct ros; simpl.
+ intro. exploit Genv.find_funct_inv; eauto. intros [fb' EQ].
+ rewrite EQ in H. rewrite Genv.find_funct_find_funct_ptr in H.
+ exists fb'; split. auto. rewrite EQ. simpl. auto.
+ destruct (Genv.find_symbol ge i); intro.
+ exists b; auto. congruence.
+Qed.
+
+(** Preservation of arguments to external functions. *)
+
+Lemma transl_extcall_arguments:
+ forall rs s sg args ts m ms,
+ Machabstr.extcall_arguments rs (parent_frame s) sg args ->
+ match_stacks_partial s ts m ms ->
+ extcall_arguments rs ms (parent_sp ts) sg args.
+Proof.
+ unfold Machabstr.extcall_arguments, extcall_arguments; intros.
+ assert (forall ty ofs v,
+ get_slot (parent_frame s) ty (Int.signed ofs) v ->
+ load_stack ms (parent_sp ts) ty ofs = Some v).
+ inv H0; simpl; intros.
+ inv H0. simpl in H2. elimtype False. generalize (AST.typesize_pos ty). omega.
+ eapply frame_match_get_slot; eauto.
+ assert (forall locs vals,
+ Machabstr.extcall_args rs (parent_frame s) locs vals ->
+ extcall_args rs ms (parent_sp ts) locs vals).
+ induction locs; intros; inversion H2; subst; clear H2.
+ constructor.
+ constructor; auto.
+ inversion H7; subst; clear H7.
+ constructor.
+ constructor. auto.
+ auto.
+Qed.
+
+Theorem step_equiv:
+ forall s1 t s2, Machabstr.step ge s1 t s2 ->
+ forall s1' (MS: match_states s1 s1') (WTS: wt_state s1),
+ exists s2', Machconcr.step ge s1' t s2' /\ match_states s2 s2'.
+Proof.
+ induction 1; intros; inv MS.
+
+ (* Mlabel *)
+ econstructor; split.
+ apply exec_Mlabel; auto.
+ econstructor; eauto with coqlib.
+
+ (* Mgetstack *)
+ exists (State ts fb (Vptr sp0 base) c (rs#dst <- v) ms); split.
+ apply exec_Mgetstack; auto. eapply frame_match_get_slot; eauto.
+ econstructor; eauto with coqlib.
+
+ (* Msetstack *)
+ assert (Val.has_type (rs src) ty).
+ inv WTS.
+ generalize (wt_function_instrs _ WTF _ (is_tail_in TAIL)); intro WTI.
+ inv WTI. apply WTRS.
+ exploit frame_match_set_slot; eauto.
+ intros [ms' [STORE [FM' [EXT' BOUND]]]].
+ exists (State ts fb (Vptr sp0 base) c rs ms'); split.
+ apply exec_Msetstack; auto.
+ econstructor; eauto.
+ eapply match_stacks_store_slot; eauto.
+
+ (* Mgetparam *)
+ exploit match_stacks_get_parent; eauto.
+ intros [parent [LOAD1 LOAD2]].
+ exists (State ts fb (Vptr sp0 base) c (rs#dst <- v) ms); split.
+ eapply exec_Mgetparam; eauto.
+ econstructor; eauto with coqlib.
+
+ (* Mop *)
+ exists (State ts fb (Vptr sp0 base) c (rs#res <- v) ms); split.
+ apply exec_Mop; auto.
+ eapply eval_operation_change_mem with (m := m); eauto.
+ intros. eapply Mem.valid_pointer_extends; eauto.
+ econstructor; eauto with coqlib.
+
+ (* Mload *)
+ exists (State ts fb (Vptr sp0 base) c (rs#dst <- v) ms); split.
+ eapply exec_Mload; eauto.
+ destruct a; simpl in H0; try discriminate.
+ simpl. eapply Mem.load_extends; eauto.
+ econstructor; eauto with coqlib.
+
+ (* Mstore *)
+ destruct a; simpl in H0; try discriminate.
+ exploit Mem.store_within_extends; eauto. intros [ms' [STORE MEXT']].
+ exists (State ts fb (Vptr sp0 base) c rs ms'); split.
+ eapply exec_Mstore; eauto.
+ econstructor; eauto with coqlib.
+ eapply match_stacks_store; eauto.
+ eapply frame_match_store; eauto.
+
+ (* Mcall *)
+ exploit find_function_find_function_ptr; eauto.
+ intros [fb' [FIND' FINDFUNCT]].
+ assert (exists ra', return_address_offset f c ra').
+ apply return_address_exists.
+ inv WTS. eapply is_tail_cons_left; eauto.
+ destruct H0 as [ra' RETADDR].
+ econstructor; split.
+ eapply exec_Mcall; eauto.
+ econstructor; eauto.
+ econstructor; eauto. inv FM; auto. exact I.
+
+ (* Mtailcall *)
+ exploit find_function_find_function_ptr; eauto.
+ intros [fb' [FIND' FINDFUNCT]].
+ exploit match_stacks_load_links; eauto. intros [LOAD1 LOAD2].
+ econstructor; split.
+ eapply exec_Mtailcall; eauto.
+ econstructor; eauto.
+ eapply match_stacks_match_stacks_partial; eauto.
+ apply free_extends; auto.
+
+ (* Malloc *)
+ caseEq (alloc ms 0 (Int.signed sz)). intros ms' blk' ALLOC.
+ exploit alloc_extends; eauto. omega. omega. intros [EQ MEXT']. subst blk'.
+ exists (State ts fb (Vptr sp0 base) c (rs#Conventions.loc_alloc_result <- (Vptr blk Int.zero)) ms'); split.
+ eapply exec_Malloc; eauto.
+ econstructor; eauto.
+ eapply match_stacks_alloc; eauto. inv MEXT; auto.
+ eapply frame_match_alloc with (mm := m) (ms := ms); eauto. inv MEXT; auto.
+
+ (* Mgoto *)
+ econstructor; split.
+ eapply exec_Mgoto; eauto.
+ econstructor; eauto.
+
+ (* Mcond *)
+ econstructor; split.
+ eapply exec_Mcond_true; eauto.
+ eapply eval_condition_change_mem with (m := m); eauto.
+ intros. eapply Mem.valid_pointer_extends; eauto.
+ econstructor; eauto.
+ econstructor; split.
+ eapply exec_Mcond_false; eauto.
+ eapply eval_condition_change_mem with (m := m); eauto.
+ intros. eapply Mem.valid_pointer_extends; eauto.
+ econstructor; eauto.
+
+ (* Mreturn *)
+ exploit match_stacks_load_links; eauto. intros [LOAD1 LOAD2].
+ econstructor; split.
+ eapply exec_Mreturn; eauto.
+ econstructor; eauto.
+ eapply match_stacks_match_stacks_partial; eauto.
+ apply free_extends; auto.
+
+ (* internal function *)
+ assert (WTF: wt_function f). inv WTS. inv H5. auto. inv WTF.
+ caseEq (alloc ms (- f.(fn_framesize))
+ (align_16_top (- f.(fn_framesize)) f.(fn_stacksize))).
+ intros ms' stk' ALLOC.
+ exploit (alloc_extends m ms m' ms' 0 (fn_stacksize f)
+ (- fn_framesize f)
+ (align_16_top (- fn_framesize f) (fn_stacksize f))); eauto.
+ omega. apply align_16_top_ge.
+ intros [EQ EXT']. subst stk'.
+ exploit (frame_match_new m ms); eauto. inv MEXT; auto.
+ intros [EQ FM]. clear EQ.
+ set (sp := Vptr stk (Int.repr (- fn_framesize f))).
+ assert (exists ms'', store Mint32 ms' stk (- fn_framesize f) (parent_sp ts) = Some ms'').
+ apply valid_access_store. constructor.
+ eauto with mem.
+ rewrite (low_bound_alloc_same _ _ _ _ _ ALLOC). omega.
+ rewrite (high_bound_alloc_same _ _ _ _ _ ALLOC).
+ change (size_chunk Mint32) with 4.
+ apply Zle_trans with 0. omega. apply align_16_top_pos.
+ destruct H0 as [ms'' STORE1].
+ assert (exists ms''', store Mint32 ms'' stk (- fn_framesize f + 12) (parent_ra ts) = Some ms''').
+ apply valid_access_store. constructor.
+ eauto with mem.
+ rewrite (low_bound_store _ _ _ _ _ _ STORE1 stk).
+ rewrite (low_bound_alloc_same _ _ _ _ _ ALLOC). omega.
+ rewrite (high_bound_store _ _ _ _ _ _ STORE1 stk).
+ rewrite (high_bound_alloc_same _ _ _ _ _ ALLOC).
+ change (size_chunk Mint32) with 4.
+ apply Zle_trans with 0. omega. apply align_16_top_pos.
+ destruct H0 as [ms''' STORE2].
+ assert (RANGE1: Int.min_signed <= - fn_framesize f <= Int.max_signed).
+ split. omega. apply Zle_trans with (-24). omega. compute;congruence.
+ assert (RANGE2: Int.min_signed <= - fn_framesize f + 12 <= Int.max_signed).
+ split. omega. apply Zle_trans with (-12). omega. compute;congruence.
+ econstructor; split.
+ eapply exec_function_internal; eauto.
+ unfold store_stack. simpl. rewrite Int.add_zero.
+ rewrite Int.signed_repr. eauto. auto.
+ unfold store_stack. simpl. rewrite Int.add_signed.
+ change (Int.signed (Int.repr 12)) with 12.
+ repeat rewrite Int.signed_repr; eauto.
+ (* match states *)
+ unfold sp; econstructor; eauto.
+ eapply match_stacks_function_entry; eauto.
+ rewrite Int.signed_repr; eauto.
+ rewrite Int.signed_repr; eauto.
+ eapply frame_match_store_other with (ms := ms''); eauto.
+ eapply frame_match_store_other with (ms := ms'); eauto.
+ simpl. right; omega. simpl. right; omega.
+ eapply store_outside_extends with (m2 := ms''); eauto.
+ eapply store_outside_extends with (m2 := ms'); eauto.
+ rewrite (low_bound_alloc_same _ _ _ _ _ H). simpl; omega.
+ rewrite (low_bound_alloc_same _ _ _ _ _ H). simpl; omega.
+
+ (* external function *)
+ econstructor; split.
+ eapply exec_function_external; eauto.
+ eapply transl_extcall_arguments; eauto.
+ econstructor; eauto.
+
+ (* return *)
+ inv STACKS.
+ econstructor; split.
+ eapply exec_return.
+ econstructor; eauto.
+Qed.
+
+Hypothesis wt_prog: wt_program p.
+
+Lemma equiv_initial_states:
+ forall st1, Machabstr.initial_state p st1 ->
+ exists st2, Machconcr.initial_state p st2 /\ match_states st1 st2 /\ wt_state st1.
+Proof.
+ intros. inversion H.
+ econstructor; split.
+ econstructor. eauto.
+ split. econstructor. constructor. apply Mem.extends_refl. auto.
+ econstructor. simpl; intros; contradiction.
+ eapply Genv.find_funct_ptr_prop; eauto.
+ red; intros; exact I.
+Qed.
+
+Lemma equiv_final_states:
+ forall st1 st2 r,
+ match_states st1 st2 /\ wt_state st1 -> Machabstr.final_state st1 r -> Machconcr.final_state st2 r.
+Proof.
+ intros. inv H0. destruct H. inv H. inv STACKS.
+ constructor; auto.
+Qed.
+
+Theorem exec_program_equiv:
+ forall (beh: program_behavior),
+ Machabstr.exec_program p beh -> Machconcr.exec_program p beh.
+Proof.
+ unfold Machconcr.exec_program, Machabstr.exec_program; intros.
+ eapply simulation_step_preservation with
+ (step1 := Machabstr.step)
+ (step2 := Machconcr.step)
+ (match_states := fun st1 st2 => match_states st1 st2 /\ wt_state st1).
+ eexact equiv_initial_states.
+ eexact equiv_final_states.
+ intros. destruct H1. exploit step_equiv; eauto.
+ intros [st2' [A B]]. exists st2'; split. auto. split. auto.
+ eapply Machtyping.subject_reduction; eauto.
+ auto.
+Qed.
+
+End SIMULATION.
diff --git a/backend/Machabstr2mach.v b/backend/Machabstr2mach.v
deleted file mode 100644
index 8a2b01d..0000000
--- a/backend/Machabstr2mach.v
+++ /dev/null
@@ -1,1185 +0,0 @@
-(** Simulation between the two semantics for the Mach language. *)
-
-Require Import Coqlib.
-Require Import Maps.
-Require Import AST.
-Require Import Integers.
-Require Import Values.
-Require Import Mem.
-Require Import Events.
-Require Import Globalenvs.
-Require Import Op.
-Require Import Locations.
-Require Import Machabstr.
-Require Import Mach.
-Require Import Machtyping.
-Require Import Stackingproof.
-
-(** Two semantics were defined for the Mach intermediate language:
-- The concrete semantics (file [Mach]), where the whole activation
- record resides in memory and the [Mgetstack], [Msetstack] and
- [Mgetparent] are interpreted as [sp]-relative memory accesses.
-- The abstract semantics (file [Machabstr]), where the activation
- record is split in two parts: the Cminor stack data, resident in
- memory, and the frame information, residing not in memory but
- in additional evaluation environments.
-
- In this file, we show a simulation result between these
- semantics: if a program executes to some result [r] in the
- abstract semantics, it also executes to the same result in
- the concrete semantics. This result bridges the correctness proof
- in file [Stackingproof] (which uses the abstract Mach semantics
- as output) and that in file [PPCgenproof] (which uses the concrete
- Mach semantics as input).
-*)
-
-Remark align_16_top_ge:
- forall lo hi,
- hi <= align_16_top lo hi.
-Proof.
- intros. unfold align_16_top. apply Zmax_bound_r.
- assert (forall x, x <= (x + 15) / 16 * 16).
- intro. assert (16 > 0). omega.
- generalize (Z_div_mod_eq (x + 15) 16 H). intro.
- replace ((x + 15) / 16 * 16) with ((x + 15) - (x + 15) mod 16).
- generalize (Z_mod_lt (x + 15) 16 H). omega.
- rewrite Zmult_comm. omega.
- generalize (H (hi - lo)). omega.
-Qed.
-
-Remark align_16_top_pos:
- forall lo hi,
- 0 <= align_16_top lo hi.
-Proof.
- intros. unfold align_16_top. apply Zmax_bound_l. omega.
-Qed.
-
-Remark size_mem_pos:
- forall sz, size_mem sz > 0.
-Proof.
- destruct sz; simpl; compute; auto.
-Qed.
-
-Remark size_type_chunk:
- forall ty, size_chunk (chunk_of_type ty) = 4 * typesize ty.
-Proof.
- destruct ty; reflexivity.
-Qed.
-
-Remark mem_chunk_type:
- forall ty, mem_chunk (chunk_of_type ty) = mem_type ty.
-Proof.
- destruct ty; reflexivity.
-Qed.
-
-Remark size_mem_type:
- forall ty, size_mem (mem_type ty) = 4 * typesize ty.
-Proof.
- destruct ty; reflexivity.
-Qed.
-
-(** * Agreement between frames and memory-resident activation records *)
-
-(** ** Agreement for one frame *)
-
-(** The core idea of the simulation proof is that for all active
- functions, the memory-allocated activation record, in the concrete
- semantics, contains the same data as the Cminor stack block
- (at positive offsets) and the frame of the function (at negative
- offsets) in the abstract semantics.
-
- This intuition (activation record = Cminor stack data + frame)
- is formalized by the following predicate [frame_match fr sp base mm ms].
- [fr] is a frame and [mm] the current memory state in the abstract
- semantics. [ms] is the current memory state in the concrete semantics.
- The stack pointer is [Vptr sp base] in both semantics. *)
-
-Inductive frame_match: frame -> block -> int -> mem -> mem -> Prop :=
- frame_match_intro:
- forall fr sp base mm ms,
- valid_block ms sp ->
- low_bound mm sp = 0 ->
- low_bound ms sp = fr.(low) ->
- high_bound ms sp = align_16_top fr.(low) (high_bound mm sp) ->
- fr.(low) <= 0 ->
- Int.min_signed <= fr.(low) ->
- base = Int.repr fr.(low) ->
- block_contents_agree fr.(low) 0 fr (ms.(blocks) sp) ->
- block_contents_agree 0 (high_bound ms sp)
- (mm.(blocks) sp) (ms.(blocks) sp) ->
- frame_match fr sp base mm ms.
-
-(** [frame_match], while presented as a relation for convenience,
- is actually a function: it fully determines the contents of the
- activation record [ms.(blocks) sp]. *)
-
-Lemma frame_match_exten:
- forall fr sp base mm ms1 ms2,
- frame_match fr sp base mm ms1 ->
- frame_match fr sp base mm ms2 ->
- ms1.(blocks) sp = ms2.(blocks) sp.
-Proof.
- intros. inversion H. inversion H0.
- unfold low_bound, high_bound in *.
- apply block_contents_exten.
- congruence.
- congruence.
- hnf; intros.
- elim H29. rewrite H3; rewrite H4; intros.
- case (zlt ofs 0); intro.
- assert (low fr <= ofs < 0). tauto.
- transitivity (contents fr ofs).
- symmetry. apply H8; auto.
- apply H22; auto.
- transitivity (contents (blocks mm sp) ofs).
- symmetry. apply H9. rewrite H4. omega.
- apply H23. rewrite H18. omega.
-Qed.
-
-(** The following two innocuous-looking lemmas are the key results
- showing that [sp]-relative memory accesses in the concrete
- semantics behave like the direct frame accesses in the abstract
- semantics. First, a value [v] that has type [ty] is preserved
- when stored in memory with chunk [chunk_of_type ty], then read
- back with the same chunk. The typing hypothesis is crucial here:
- for instance, a float value reads back as [Vundef] when stored
- and load with chunk [Mint32]. *)
-
-Lemma load_result_ty:
- forall v ty,
- Val.has_type v ty -> Val.load_result (chunk_of_type ty) v = v.
-Proof.
- destruct v; destruct ty; simpl; contradiction || reflexivity.
-Qed.
-
-(** Second, computations of [sp]-relative offsets using machine
- arithmetic (as done in the concrete semantics) never overflows
- and behaves identically to the offset computations using exact
- arithmetic (as done in the abstract semantics). *)
-
-Lemma int_add_no_overflow:
- forall x y,
- Int.min_signed <= Int.signed x + Int.signed y <= Int.max_signed ->
- Int.signed (Int.add x y) = Int.signed x + Int.signed y.
-Proof.
- intros. rewrite Int.add_signed. rewrite Int.signed_repr. auto. auto.
-Qed.
-
-(** Given matching frames and activation records, loading from the
- activation record (in the concrete semantics) behaves identically
- to reading the corresponding slot from the frame
- (in the abstract semantics). *)
-
-Lemma frame_match_get_slot:
- forall fr sp base mm ms ty ofs v,
- frame_match fr sp base mm ms ->
- get_slot fr ty (Int.signed ofs) v ->
- Val.has_type v ty ->
- load_stack ms (Vptr sp base) ty ofs = Some v.
-Proof.
- intros. inversion H. inversion H0. subst v.
- unfold load_stack, Val.add, loadv.
- assert (Int.signed base = low fr).
- rewrite H8. apply Int.signed_repr.
- split. auto. apply Zle_trans with 0. auto. compute; congruence.
- assert (Int.signed (Int.add base ofs) = low fr + Int.signed ofs).
- rewrite int_add_no_overflow. rewrite H18. auto.
- rewrite H18. split. omega. apply Zle_trans with 0.
- generalize (typesize_pos ty). omega. compute. congruence.
- rewrite H23.
- assert (BND1: low_bound ms sp <= low fr + Int.signed ofs).
- omega.
- assert (BND2: (low fr + Int.signed ofs) + size_chunk (chunk_of_type ty) <= high_bound ms sp).
- rewrite size_type_chunk. apply Zle_trans with 0.
- assumption. rewrite H5. apply align_16_top_pos.
- generalize (load_in_bounds (chunk_of_type ty) ms sp (low fr + Int.signed ofs) H2 BND1 BND2).
- intros [v' LOAD].
- generalize (load_inv _ _ _ _ _ LOAD).
- intros [A [B [C D]]].
- rewrite LOAD. rewrite <- D.
- decEq. rewrite mem_chunk_type.
- rewrite <- size_mem_type in H17.
- assert (low fr <= low fr + Int.signed ofs). omega.
- generalize (load_contentmap_agree _ _ _ _ _ _ H9 H24 H17).
- intro. rewrite H25.
- apply load_result_ty.
- assumption.
-Qed.
-
-(** Loads from [sp], corresponding to accesses to Cminor stack data
- in the abstract semantics, give the same results in the concrete
- semantics. This is because the offset from [sp] must be positive or
- null for the original load to succeed, and because the part
- of the activation record at positive offsets matches the Cminor
- stack data block. *)
-
-Lemma frame_match_load:
- forall fr sp base mm ms chunk ofs v,
- frame_match fr sp base mm ms ->
- load chunk mm sp ofs = Some v ->
- load chunk ms sp ofs = Some v.
-Proof.
- intros. inversion H.
- generalize (load_inv _ _ _ _ _ H0). intros [A [B [C D]]].
- change (low (blocks mm sp)) with (low_bound mm sp) in B.
- change (high (blocks mm sp)) with (high_bound mm sp) in C.
- unfold load. rewrite zlt_true; auto.
- rewrite in_bounds_holds.
- rewrite <- D. decEq. decEq. eapply load_contentmap_agree.
- red in H9. eexact H9.
- omega.
- unfold size_chunk in C. rewrite H4.
- apply Zle_trans with (high_bound mm sp). auto.
- apply align_16_top_ge.
- change (low (blocks ms sp)) with (low_bound ms sp).
- rewrite H3. omega.
- change (high (blocks ms sp)) with (high_bound ms sp).
- rewrite H4. apply Zle_trans with (high_bound mm sp). auto.
- apply align_16_top_ge.
-Qed.
-
-(** Assigning a value to a frame slot (in the abstract semantics)
- corresponds to storing this value in the activation record
- (in the concrete semantics). Moreover, agreement between frames
- and activation records is preserved. *)
-
-Lemma frame_match_set_slot:
- forall fr sp base mm ms ty ofs v fr',
- frame_match fr sp base mm ms ->
- set_slot fr ty (Int.signed ofs) v fr' ->
- exists ms',
- store_stack ms (Vptr sp base) ty ofs v = Some ms' /\
- frame_match fr' sp base mm ms'.
-Proof.
- intros. inversion H. inversion H0. subst ty0.
- unfold store_stack, Val.add, storev.
- assert (Int.signed base = low fr).
- rewrite H7. apply Int.signed_repr.
- split. auto. apply Zle_trans with 0. auto. compute; congruence.
- assert (Int.signed (Int.add base ofs) = low fr + Int.signed ofs).
- rewrite int_add_no_overflow. rewrite H16. auto.
- rewrite H16. split. omega. apply Zle_trans with 0.
- generalize (typesize_pos ty). omega. compute. congruence.
- rewrite H20.
- assert (BND1: low_bound ms sp <= low fr + Int.signed ofs).
- omega.
- assert (BND2: (low fr + Int.signed ofs) + size_chunk (chunk_of_type ty) <= high_bound ms sp).
- rewrite size_type_chunk. rewrite H4.
- apply Zle_trans with 0. subst ofs0. auto. apply align_16_top_pos.
- generalize (store_in_bounds _ _ _ _ v H1 BND1 BND2).
- intros [ms' STORE].
- generalize (store_inv _ _ _ _ _ _ STORE). intros [P [Q [R [S [x T]]]]].
- generalize (low_bound_store _ _ _ _ sp _ _ STORE). intro LB.
- generalize (high_bound_store _ _ _ _ sp _ _ STORE). intro HB.
- exists ms'.
- split. exact STORE.
- apply frame_match_intro; auto.
- eapply valid_block_store; eauto.
- rewrite LB. auto.
- rewrite HB. auto.
- red. rewrite T; rewrite update_s; simpl.
- rewrite mem_chunk_type.
- subst ofs0. eapply store_contentmap_agree; eauto.
- rewrite HB; rewrite T; rewrite update_s.
- red. simpl. apply store_contentmap_outside_agree.
- assumption. left. rewrite mem_chunk_type.
- rewrite size_mem_type. subst ofs0. auto.
-Qed.
-
-(** Agreement is preserved by stores within blocks other than the
- one pointed to by [sp]. *)
-
-Lemma frame_match_store_stack_other:
- forall fr sp base mm ms sp' base' ty ofs v ms',
- frame_match fr sp base mm ms ->
- store_stack ms (Vptr sp' base') ty ofs v = Some ms' ->
- sp <> sp' ->
- frame_match fr sp base mm ms'.
-Proof.
- unfold store_stack, Val.add, storev. intros. inversion H.
- generalize (store_inv _ _ _ _ _ _ H0). intros [P [Q [R [S [x T]]]]].
- generalize (low_bound_store _ _ _ _ sp _ _ H0). intro LB.
- generalize (high_bound_store _ _ _ _ sp _ _ H0). intro HB.
- apply frame_match_intro; auto.
- eapply valid_block_store; eauto.
- rewrite LB; auto.
- rewrite HB; auto.
- rewrite T; rewrite update_o; auto.
- rewrite HB; rewrite T; rewrite update_o; auto.
-Qed.
-
-(** Stores relative to [sp], corresponding to accesses to Cminor stack data
- in the abstract semantics, give the same results in the concrete
- semantics. Moreover, agreement between frames and activation
- records is preserved. *)
-
-Lemma frame_match_store_ok:
- forall fr sp base mm ms chunk ofs v mm',
- frame_match fr sp base mm ms ->
- store chunk mm sp ofs v = Some mm' ->
- exists ms', store chunk ms sp ofs v = Some ms'.
-Proof.
- intros. inversion H.
- generalize (store_inv _ _ _ _ _ _ H0). intros [P [Q [R [S [x T]]]]].
- change (low (blocks mm sp)) with (low_bound mm sp) in Q.
- change (high (blocks mm sp)) with (high_bound mm sp) in R.
- apply store_in_bounds.
- auto.
- omega.
- apply Zle_trans with (high_bound mm sp).
- auto. rewrite H4. apply align_16_top_ge.
-Qed.
-
-Lemma frame_match_store:
- forall fr sp base mm ms chunk b ofs v mm' ms',
- frame_match fr sp base mm ms ->
- store chunk mm b ofs v = Some mm' ->
- store chunk ms b ofs v = Some ms' ->
- frame_match fr sp base mm' ms'.
-Proof.
- intros. inversion H.
- generalize (store_inv _ _ _ _ _ _ H1). intros [A [B [C [D [x1 E]]]]].
- generalize (store_inv _ _ _ _ _ _ H0). intros [I [J [K [L [x2 M]]]]].
- generalize (low_bound_store _ _ _ _ sp _ _ H0). intro LBm.
- generalize (low_bound_store _ _ _ _ sp _ _ H1). intro LBs.
- generalize (high_bound_store _ _ _ _ sp _ _ H0). intro HBm.
- generalize (high_bound_store _ _ _ _ sp _ _ H1). intro HBs.
- apply frame_match_intro; auto.
- eapply valid_block_store; eauto.
- congruence. congruence. congruence.
- rewrite E. unfold update. case (zeq sp b); intro.
- subst b. red; simpl.
- apply store_contentmap_outside_agree; auto.
- right. unfold low_bound in H3. omega.
- assumption.
- rewrite HBs; rewrite E; rewrite M; unfold update.
- case (zeq sp b); intro.
- subst b. red; simpl.
- apply store_contentmap_agree; auto.
- assumption.
-Qed.
-
-(** Memory allocation of the Cminor stack data block (in the abstract
- semantics) and of the whole activation record (in the concrete
- semantics) return memory states that agree according to [frame_match].
- Moreover, [frame_match] relations over already allocated blocks
- remain true. *)
-
-Lemma frame_match_new:
- forall mm ms mm' ms' sp sp' f,
- mm.(nextblock) = ms.(nextblock) ->
- alloc mm 0 f.(fn_stacksize) = (mm', sp) ->
- alloc ms (- f.(fn_framesize)) (align_16_top (- f.(fn_framesize)) f.(fn_stacksize)) = (ms', sp') ->
- f.(fn_framesize) >= 0 ->
- f.(fn_framesize) <= -Int.min_signed ->
- frame_match (init_frame f) sp (Int.repr (-f.(fn_framesize))) mm' ms'.
-Proof.
- intros.
- injection H0; intros. injection H1; intros.
- assert (sp = sp'). congruence. rewrite <- H8 in H6. subst sp'.
- generalize (low_bound_alloc _ _ sp _ _ _ H0). rewrite zeq_true. intro LBm.
- generalize (low_bound_alloc _ _ sp _ _ _ H1). rewrite zeq_true. intro LBs.
- generalize (high_bound_alloc _ _ sp _ _ _ H0). rewrite zeq_true. intro HBm.
- generalize (high_bound_alloc _ _ sp _ _ _ H1). rewrite zeq_true. intro HBs.
- apply frame_match_intro; auto.
- eapply valid_new_block; eauto.
- simpl. congruence.
- simpl. omega.
- simpl. omega.
- rewrite <- H7. simpl. rewrite H6; simpl. rewrite update_s.
- hnf; simpl; auto.
- rewrite HBs; rewrite <- H5; simpl; rewrite H4; rewrite <- H7; simpl; rewrite H6; simpl;
- repeat (rewrite update_s).
- hnf; simpl; auto.
-Qed.
-
-Lemma frame_match_alloc:
- forall mm ms fr sp base lom him los his mm' ms' bm bs,
- mm.(nextblock) = ms.(nextblock) ->
- frame_match fr sp base mm ms ->
- alloc mm lom him = (mm', bm) ->
- alloc ms los his = (ms', bs) ->
- frame_match fr sp base mm' ms'.
-Proof.
- intros. inversion H0.
- assert (sp <> bm).
- apply valid_not_valid_diff with mm.
- red. rewrite H. exact H3.
- eapply fresh_block_alloc; eauto.
- assert (sp <> bs).
- apply valid_not_valid_diff with ms. auto.
- eapply fresh_block_alloc; eauto.
- generalize (low_bound_alloc _ _ sp _ _ _ H1).
- rewrite zeq_false; auto; intro LBm.
- generalize (low_bound_alloc _ _ sp _ _ _ H2).
- rewrite zeq_false; auto; intro LBs.
- generalize (high_bound_alloc _ _ sp _ _ _ H1).
- rewrite zeq_false; auto; intro HBm.
- generalize (high_bound_alloc _ _ sp _ _ _ H2).
- rewrite zeq_false; auto; intro HBs.
- apply frame_match_intro.
- eapply valid_block_alloc; eauto.
- congruence. congruence. congruence. auto. auto. auto.
- injection H2; intros. rewrite <- H20; simpl; rewrite H19; simpl.
- rewrite update_o; auto.
- rewrite HBs;
- injection H2; intros. rewrite <- H20; simpl; rewrite H19; simpl.
- injection H1; intros. rewrite <- H22; simpl; rewrite H21; simpl.
- repeat (rewrite update_o; auto).
-Qed.
-
-(** [frame_match] relations are preserved by freeing a block
- other than the one pointed to by [sp]. *)
-
-Lemma frame_match_free:
- forall fr sp base mm ms b,
- frame_match fr sp base mm ms ->
- sp <> b ->
- frame_match fr sp base (free mm b) (free ms b).
-Proof.
- intros. inversion H.
- generalize (low_bound_free mm _ _ H0); intro LBm.
- generalize (low_bound_free ms _ _ H0); intro LBs.
- generalize (high_bound_free mm _ _ H0); intro HBm.
- generalize (high_bound_free ms _ _ H0); intro HBs.
- apply frame_match_intro; auto.
- congruence. congruence. congruence.
- unfold free; simpl. rewrite update_o; auto.
- rewrite HBs.
- unfold free; simpl. repeat (rewrite update_o; auto).
-Qed.
-
-(** ** Agreement for all the frames in a call stack *)
-
-(** We need to reason about all the frames and activation records
- active at any given time during the executions: not just
- about those for the currently executing function, but also
- those for the callers. These collections of
- active frames are called ``call stacks''. They are lists
- of triples representing a frame and a stack pointer
- (reference and offset) in the abstract semantics. *)
-
-Definition callstack : Set := list (frame * block * int).
-
-(** The correct linking of frames (each frame contains a pointer
- to the frame of its caller at the lowest offset) is captured
- by the following predicate. *)
-
-Inductive callstack_linked: callstack -> Prop :=
- | callstack_linked_nil:
- callstack_linked nil
- | callstack_linked_one:
- forall fr1 sp1 base1,
- callstack_linked ((fr1, sp1, base1) :: nil)
- | callstack_linked_cons:
- forall fr1 sp1 base1 fr2 base2 sp2 cs,
- get_slot fr1 Tint 0 (Vptr sp2 base2) ->
- callstack_linked ((fr2, sp2, base2) :: cs) ->
- callstack_linked ((fr1, sp1, base1) :: (fr2, sp2, base2) :: cs).
-
-(** [callstack_dom cs b] (read: call stack [cs] is ``dominated''
- by block reference [b]) means that the stack pointers in [cs]
- strictly decrease and are all below [b]. This ensures that
- the stack block for a function was allocated after that for its
- callers. A consequence is that no two active functions share
- the same stack block. *)
-
-Inductive callstack_dom: callstack -> block -> Prop :=
- | callstack_dom_nil:
- forall b, callstack_dom nil b
- | callstack_dom_cons:
- forall fr sp base cs b,
- sp < b ->
- callstack_dom cs sp ->
- callstack_dom ((fr, sp, base) :: cs) b.
-
-Lemma callstack_dom_less:
- forall cs b, callstack_dom cs b ->
- forall fr sp base, In (fr, sp, base) cs -> sp < b.
-Proof.
- induction 1. simpl. tauto.
- simpl. intros fr0 sp0 base0 [A|B].
- injection A; intros; subst fr0; subst sp0; subst base0. auto.
- apply Zlt_trans with sp. eapply IHcallstack_dom; eauto. auto.
-Qed.
-
-Lemma callstack_dom_diff:
- forall cs b, callstack_dom cs b ->
- forall fr sp base, In (fr, sp, base) cs -> sp <> b.
-Proof.
- intros. apply Zlt_not_eq. eapply callstack_dom_less; eauto.
-Qed.
-
-Lemma callstack_dom_incr:
- forall cs b, callstack_dom cs b ->
- forall b', b < b' -> callstack_dom cs b'.
-Proof.
- induction 1; intros.
- apply callstack_dom_nil.
- apply callstack_dom_cons. omega. auto.
-Qed.
-
-(** Every block reference is either ``in'' a call stack (that is,
- refers to the stack block of one of the calls) or ``not in''
- a call stack (that is, differs from all the stack blocks). *)
-
-Inductive notin_callstack: block -> callstack -> Prop :=
- | notin_callstack_nil:
- forall b, notin_callstack b nil
- | notin_callstack_cons:
- forall b fr sp base cs,
- b <> sp ->
- notin_callstack b cs ->
- notin_callstack b ((fr, sp, base) :: cs).
-
-Lemma in_or_notin_callstack:
- forall b cs,
- (exists fr, exists base, In (fr, b, base) cs) \/ notin_callstack b cs.
-Proof.
- induction cs.
- right; constructor.
- elim IHcs.
- intros [fr [base IN]]. left. exists fr; exists base; auto with coqlib.
- intro NOTIN. destruct a. destruct p. case (eq_block b b0); intro.
- left. exists f; exists i. subst b0. auto with coqlib.
- right. apply notin_callstack_cons; auto.
-Qed.
-
-(** [callstack_invariant cs mm ms] relates the memory state [mm]
- from the abstract semantics with the memory state [ms] from the
- concrete semantics, relative to the current call stack [cs].
- Five conditions are enforced:
-- All frames in [cs] agree with the corresponding activation records
- (in the sense of [frame_match]).
-- The frames in the call stack are properly linked.
-- Memory blocks that are not activation records for active function
- calls are exactly identical in [mm] and [ms].
-- The allocation pointers are the same in [mm] and [ms].
-- The call stack [cs] is ``dominated'' by this allocation pointer,
- implying that all activation records are valid, allocated blocks,
- pairwise disjoint, and they were allocated in the order implied
- by [cs]. *)
-
-Record callstack_invariant (cs: callstack) (mm ms: mem) : Prop :=
- mk_callstack_invariant {
- cs_frame:
- forall fr sp base,
- In (fr, sp, base) cs -> frame_match fr sp base mm ms;
- cs_linked:
- callstack_linked cs;
- cs_others:
- forall b, notin_callstack b cs ->
- mm.(blocks) b = ms.(blocks) b;
- cs_next:
- mm.(nextblock) = ms.(nextblock);
- cs_dom:
- callstack_dom cs ms.(nextblock)
- }.
-
-(** Again, while [callstack_invariant] is presented as a relation,
- it actually fully determines the concrete memory state [ms]
- from the abstract memory state [mm] and the call stack [cs]. *)
-
-Lemma callstack_exten:
- forall cs mm ms1 ms2,
- callstack_invariant cs mm ms1 ->
- callstack_invariant cs mm ms2 ->
- ms1 = ms2.
-Proof.
- intros. inversion H; inversion H0.
- apply mem_exten.
- congruence.
- intros. elim (in_or_notin_callstack b cs).
- intros [fr [base FM]]. apply frame_match_exten with fr base mm; auto.
- intro. transitivity (blocks mm b).
- symmetry. auto. auto.
-Qed.
-
-(** The following properties of [callstack_invariant] are the
- building blocks for the proof of simulation. First, a [get_slot]
- operation in the abstract semantics corresponds to a [sp]-relative
- memory load in the concrete semantics. *)
-
-Lemma callstack_get_slot:
- forall fr sp base cs mm ms ty ofs v,
- callstack_invariant ((fr, sp, base) :: cs) mm ms ->
- get_slot fr ty (Int.signed ofs) v ->
- Val.has_type v ty ->
- load_stack ms (Vptr sp base) ty ofs = Some v.
-Proof.
- intros. inversion H.
- apply frame_match_get_slot with fr mm.
- apply cs_frame0. apply in_eq.
- auto. auto.
-Qed.
-
-(** Similarly, a [get_parent] operation corresponds to loading
- the back-link from the current activation record, then loading
- from this back-link. *)
-
-Lemma callstack_get_parent:
- forall fr1 sp1 base1 fr2 sp2 base2 cs mm ms ty ofs v,
- callstack_invariant ((fr1, sp1, base1) :: (fr2, sp2, base2) :: cs) mm ms ->
- get_slot fr2 ty (Int.signed ofs) v ->
- Val.has_type v ty ->
- load_stack ms (Vptr sp1 base1) Tint (Int.repr 0) = Some (Vptr sp2 base2) /\
- load_stack ms (Vptr sp2 base2) ty ofs = Some v.
-Proof.
- intros. inversion H. split.
- inversion cs_linked0.
- apply frame_match_get_slot with fr1 mm.
- apply cs_frame0. auto with coqlib.
- rewrite Int.signed_repr. auto. compute. intuition congruence.
- exact I.
- apply frame_match_get_slot with fr2 mm.
- apply cs_frame0. auto with coqlib.
- auto. auto.
-Qed.
-
-(** A memory load valid in the abstract semantics can also be performed
- in the concrete semantics. *)
-
-Lemma callstack_load:
- forall cs chunk mm ms a v,
- callstack_invariant cs mm ms ->
- loadv chunk mm a = Some v ->
- loadv chunk ms a = Some v.
-Proof.
- unfold loadv. intros. destruct a; try discriminate.
- inversion H.
- elim (in_or_notin_callstack b cs).
- intros [fr [base IN]]. apply frame_match_load with fr base mm; auto.
- intro. rewrite <- H0. unfold load.
- rewrite (cs_others0 b H1). rewrite cs_next0. reflexivity.
-Qed.
-
-(** A [set_slot] operation in the abstract semantics corresponds
- to a [sp]-relative memory store in the concrete semantics.
- Moreover, the property [callstack_invariant] still holds for
- the final call stacks and memory states. *)
-
-Lemma callstack_set_slot:
- forall fr sp base cs mm ms ty ofs v fr',
- callstack_invariant ((fr, sp, base) :: cs) mm ms ->
- set_slot fr ty (Int.signed ofs) v fr' ->
- 4 <= Int.signed ofs ->
- exists ms',
- store_stack ms (Vptr sp base) ty ofs v = Some ms' /\
- callstack_invariant ((fr', sp, base) :: cs) mm ms'.
-Proof.
- intros. inversion H.
- assert (frame_match fr sp base mm ms). apply cs_frame0. apply in_eq.
- generalize (frame_match_set_slot _ _ _ _ _ _ _ _ _ H2 H0).
- intros [ms' [SS FM]].
- generalize (store_inv _ _ _ _ _ _ SS). intros [A [B [C [D [x E]]]]].
- exists ms'.
- split. auto.
- constructor.
- (* cs_frame *)
- intros. elim H3; intros.
- injection H4; intros; clear H4.
- subst fr0; subst sp0; subst base0. auto.
- apply frame_match_store_stack_other with ms sp base ty ofs v.
- apply cs_frame0. auto with coqlib. auto.
- apply callstack_dom_diff with cs fr0 base0. inversion cs_dom0; auto. auto.
- (* cs_linked *)
- inversion cs_linked0. apply callstack_linked_one.
- apply callstack_linked_cons.
- eapply slot_gso; eauto.
- auto.
- (* cs_others *)
- intros. inversion H3.
- rewrite E; simpl. rewrite update_o; auto. apply cs_others0.
- constructor; auto.
- (* cs_next *)
- congruence.
- (* cs_dom *)
- inversion cs_dom0. constructor. rewrite D; auto. auto.
-Qed.
-
-(** A memory store in the abstract semantics can also be performed
- in the concrete semantics. Moreover, the property
- [callstack_invariant] is preserved. *)
-
-Lemma callstack_store_aux:
- forall cs mm ms chunk b ofs v mm' ms',
- callstack_invariant cs mm ms ->
- store chunk mm b ofs v = Some mm' ->
- store chunk ms b ofs v = Some ms' ->
- callstack_invariant cs mm' ms'.
-Proof.
- intros. inversion H.
- generalize (store_inv _ _ _ _ _ _ H0). intros [A [B [C [D [x E]]]]].
- generalize (store_inv _ _ _ _ _ _ H1). intros [P [Q [R [S [y T]]]]].
- constructor; auto.
- (* cs_frame *)
- intros. eapply frame_match_store; eauto.
- (* cs_others *)
- intros. generalize (cs_others0 b0 H2); intro.
- rewrite E; rewrite T; unfold update.
- case (zeq b0 b); intro.
- subst b0.
- generalize x; generalize y. rewrite H3.
- intros. replace y0 with x0. reflexivity. apply proof_irrelevance.
- auto.
- (* cs_nextblock *)
- congruence.
- (* cs_dom *)
- rewrite S. auto.
-Qed.
-
-Lemma callstack_store_ok:
- forall cs mm ms chunk b ofs v mm',
- callstack_invariant cs mm ms ->
- store chunk mm b ofs v = Some mm' ->
- exists ms', store chunk ms b ofs v = Some ms'.
-Proof.
- intros. inversion H.
- elim (in_or_notin_callstack b cs).
- intros [fr [base IN]].
- apply frame_match_store_ok with fr base mm mm'; auto.
- intro. generalize (cs_others0 b H1). intro.
- generalize (store_inv _ _ _ _ _ _ H0).
- rewrite cs_next0; rewrite H2. intros [A [B [C [D [x E]]]]].
- apply store_in_bounds; auto.
-Qed.
-
-Lemma callstack_store:
- forall cs mm ms chunk a v mm',
- callstack_invariant cs mm ms ->
- storev chunk mm a v = Some mm' ->
- exists ms',
- storev chunk ms a v = Some ms' /\
- callstack_invariant cs mm' ms'.
-Proof.
- unfold storev; intros. destruct a; try discriminate.
- generalize (callstack_store_ok _ _ _ _ _ _ _ _ H H0).
- intros [ms' STORE].
- exists ms'. split. auto. eapply callstack_store_aux; eauto.
-Qed.
-
-(** Allocations of heap blocks can be performed in parallel in
- both semantics, preserving [callstack_invariant]. *)
-
-Lemma callstack_alloc:
- forall cs mm ms lo hi mm' blk,
- callstack_invariant cs mm ms ->
- Mem.alloc mm lo hi = (mm', blk) ->
- exists ms',
- Mem.alloc ms lo hi = (ms', blk) /\
- callstack_invariant cs mm' ms'.
-Proof.
- intros. inversion H.
- caseEq (alloc ms lo hi). intros ms' blk' ALLOC'.
- injection H0; intros. injection ALLOC'; intros.
- assert (blk' = blk). congruence. rewrite H5 in H3. rewrite H5.
- exists ms'; split. auto.
- constructor.
- (* frame *)
- intros; eapply frame_match_alloc; eauto.
- (* linked *)
- auto.
- (* others *)
- intros. rewrite <- H2; rewrite <- H4; simpl.
- rewrite H1; rewrite H3. unfold update. case (zeq b blk); auto.
- (* next *)
- rewrite <- H2; rewrite <- H4; simpl; congruence.
- (* dom *)
- eapply callstack_dom_incr; eauto. rewrite <- H4; simpl. omega.
-Qed.
-
-(** At function entry, a new frame is pushed on the call stack,
- and memory blocks are allocated in both semantics. Moreover,
- the back link to the caller's activation record is set up
- in the concrete semantics. All this preserves [callstack_invariant]. *)
-
-Lemma callstack_function_entry:
- forall fr0 sp0 base0 cs mm ms f fr mm' sp ms' sp',
- callstack_invariant ((fr0, sp0, base0) :: cs) mm ms ->
- alloc mm 0 f.(fn_stacksize) = (mm', sp) ->
- alloc ms (- f.(fn_framesize)) (align_16_top (- f.(fn_framesize)) f.(fn_stacksize)) = (ms', sp') ->
- f.(fn_framesize) >= 0 ->
- f.(fn_framesize) <= -Int.min_signed ->
- set_slot (init_frame f) Tint 0 (Vptr sp0 base0) fr ->
- let base := Int.repr (-f.(fn_framesize)) in
- exists ms'',
- store_stack ms' (Vptr sp base) Tint (Int.repr 0) (Vptr sp0 base0) = Some ms''
- /\ callstack_invariant ((fr, sp, base) :: (fr0, sp0, base0) :: cs) mm' ms''
- /\ sp' = sp.
-Proof.
- assert (ZERO: 0 = Int.signed (Int.repr 0)).
- rewrite Int.signed_repr. auto. compute; intuition congruence.
- intros. inversion H.
- injection H0; intros. injection H1; intros.
- assert (sp' = sp). congruence. rewrite H9 in H7. subst sp'.
- assert (frame_match (init_frame f) sp base mm' ms').
- unfold base. eapply frame_match_new; eauto.
- rewrite ZERO in H4.
- generalize (frame_match_set_slot _ _ _ _ _ _ _ _ _ H9 H4).
- intros [ms'' [SS FM]].
- generalize (store_inv _ _ _ _ _ _ SS).
- intros [A [B [C [D [x E]]]]].
- exists ms''. split; auto. split.
- constructor.
- (* cs_frame *)
- intros. elim H10; intro.
- injection H11; intros; clear H11.
- subst fr1; subst sp1; subst base1. auto.
- eapply frame_match_store_stack_other; eauto.
- eapply frame_match_alloc; [idtac|idtac|eexact H0|eexact H1].
- congruence. eapply cs_frame; eauto with coqlib.
- rewrite <- H7. eapply callstack_dom_diff; eauto with coqlib.
- (* cs_linked *)
- constructor. rewrite ZERO. eapply slot_gss; eauto. auto.
- (* cs_others *)
- intros. inversion H10.
- rewrite E; rewrite update_o; auto.
- rewrite <- H6; rewrite <- H8; simpl; rewrite H5; rewrite H7; simpl.
- repeat (rewrite update_o; auto).
- (* cs_next *)
- rewrite D. rewrite <- H6; rewrite <- H8; simpl. congruence.
- (* cs_dom *)
- constructor. rewrite D; auto. rewrite <- H7. auto.
- auto.
-Qed.
-
-(** At function return, the memory blocks corresponding to Cminor
- stack data and activation record for the function are freed.
- This preserves [callstack_invariant]. *)
-
-Lemma callstack_function_return:
- forall fr sp base cs mm ms,
- callstack_invariant ((fr, sp, base) :: cs) mm ms ->
- callstack_invariant cs (free mm sp) (free ms sp).
-Proof.
- intros. inversion H. inversion cs_dom0.
- constructor.
- (* cs_frame *)
- intros. apply frame_match_free. apply cs_frame0; auto with coqlib.
- apply callstack_dom_diff with cs fr1 base1. auto. auto.
- (* cs_linked *)
- inversion cs_linked0. apply callstack_linked_nil. auto.
- (* cs_others *)
- intros.
- unfold free; simpl; unfold update.
- case (zeq b0 sp); intro.
- auto.
- apply cs_others0. apply notin_callstack_cons; auto.
- (* cs_nextblock *)
- simpl. auto.
- (* cs_dom *)
- simpl. apply callstack_dom_incr with sp; auto.
-Qed.
-
-(** Finally, [callstack_invariant] holds for the initial memory states
- in the two semantics. *)
-
-Lemma callstack_init:
- forall (p: program),
- callstack_invariant ((empty_frame, nullptr, Int.zero) :: nil)
- (Genv.init_mem p) (Genv.init_mem p).
-Proof.
- intros.
- generalize (Genv.initmem_nullptr p). intros [A B].
- constructor.
- (* cs_frame *)
- intros. elim H; intro.
- injection H0; intros; subst fr; subst sp; subst base.
- constructor.
- assumption.
- unfold low_bound. rewrite B. reflexivity.
- unfold low_bound, empty_frame. rewrite B. reflexivity.
- unfold high_bound. rewrite B. reflexivity.
- simpl. omega.
- simpl. compute. intuition congruence.
- reflexivity.
- rewrite B. unfold empty_frame. simpl. hnf. auto.
- rewrite B. hnf. auto.
- elim H0.
- (* cs_linked *)
- apply callstack_linked_one.
- (* cs_others *)
- auto.
- (* cs_nextblock *)
- reflexivity.
- (* cs_dom *)
- constructor. exact A. constructor.
-Qed.
-
-(** Preservation of arguments to external functions. *)
-
-Lemma transl_extcall_arguments:
- forall rs fr sg args stk base cs m ms,
- Machabstr.extcall_arguments rs fr sg args ->
- callstack_invariant ((fr, stk, base) :: cs) m ms ->
- wt_frame fr ->
- extcall_arguments rs ms (Vptr stk base) sg args.
-Proof.
- unfold Machabstr.extcall_arguments, extcall_arguments; intros.
- assert (forall locs vals,
- Machabstr.extcall_args rs fr locs vals ->
- extcall_args rs ms (Vptr stk base) locs vals).
- induction locs; intros; inversion H2; subst; clear H2.
- constructor.
- constructor; auto.
- inversion H7; subst; clear H7.
- constructor.
- constructor. eapply callstack_get_slot; eauto.
- eapply wt_get_slot; eauto.
- auto.
-Qed.
-
-(** * The proof of simulation *)
-
-Section SIMULATION.
-
-Variable p: program.
-Hypothesis wt_p: wt_program p.
-Let ge := Genv.globalenv p.
-
-(** The proof of simulation relies on diagrams of the following form:
-<<
- sp, parent, c, rs, fr, mm ----------- sp, c, rs, ms
- | |
- | |
- v v
- sp, parent, c', rs', fr', mm' -------- sp, c', rs', ms'
->>
- The left vertical arrow is a transition in the abstract semantics.
- The right vertical arrow is a transition in the concrete semantics.
- The precondition (top horizontal line) is the appropriate
- [callstack_invariant] property between the initial memory states
- [mm] and [ms] and any call stack with [fr] as top frame and
- [parent] as second frame. In addition, well-typedness conditions
- over the code [c], the register [rs] and the frame [fr] are demanded.
- The postcondition (bottom horizontal line) is [callstack_invariant]
- between the final memory states [mm'] and [ms'] and the final
- call stack.
-*)
-
-Definition exec_instr_prop
- (f: function) (sp: val) (parent: frame)
- (c: code) (rs: regset) (fr: frame) (mm: mem) (t: trace)
- (c': code) (rs': regset) (fr': frame) (mm': mem) : Prop :=
- forall ms stk base pstk pbase cs
- (WTF: wt_function f)
- (INCL: incl c f.(fn_code))
- (WTRS: wt_regset rs)
- (WTFR: wt_frame fr)
- (WTPA: wt_frame parent)
- (CSI: callstack_invariant ((fr, stk, base) :: (parent, pstk, pbase) :: cs) mm ms)
- (SP: sp = Vptr stk base),
- exists ms',
- exec_instr ge f sp c rs ms t c' rs' ms' /\
- callstack_invariant ((fr', stk, base) :: (parent, pstk, pbase) :: cs) mm' ms'.
-
-Definition exec_instrs_prop
- (f: function) (sp: val) (parent: frame)
- (c: code) (rs: regset) (fr: frame) (mm: mem) (t: trace)
- (c': code) (rs': regset) (fr': frame) (mm': mem) : Prop :=
- forall ms stk base pstk pbase cs
- (WTF: wt_function f)
- (INCL: incl c f.(fn_code))
- (WTRS: wt_regset rs)
- (WTFR: wt_frame fr)
- (WTPA: wt_frame parent)
- (CSI: callstack_invariant ((fr, stk, base) :: (parent, pstk, pbase) :: cs) mm ms)
- (SP: sp = Vptr stk base),
- exists ms',
- exec_instrs ge f sp c rs ms t c' rs' ms' /\
- callstack_invariant ((fr', stk, base) :: (parent, pstk, pbase) :: cs) mm' ms'.
-
-Definition exec_function_body_prop
- (f: function) (parent: frame) (link ra: val)
- (rs: regset) (mm: mem) (t: trace)
- (rs': regset) (mm': mem) : Prop :=
- forall ms pstk pbase cs
- (WTF: wt_function f)
- (WTRS: wt_regset rs)
- (WTPA: wt_frame parent)
- (WTRA: Val.has_type ra Tint)
- (LINK: link = Vptr pstk pbase)
- (CSI: callstack_invariant ((parent, pstk, pbase) :: cs) mm ms),
- exists ms',
- exec_function_body ge f (Vptr pstk pbase) ra rs ms t rs' ms' /\
- callstack_invariant ((parent, pstk, pbase) :: cs) mm' ms'.
-
-Definition exec_function_prop
- (f: fundef) (parent: frame)
- (rs: regset) (mm: mem) (t: trace)
- (rs': regset) (mm': mem) : Prop :=
- forall ms pstk pbase cs
- (WTF: wt_fundef f)
- (WTRS: wt_regset rs)
- (WTPA: wt_frame parent)
- (CSI: callstack_invariant ((parent, pstk, pbase) :: cs) mm ms),
- exists ms',
- exec_function ge f (Vptr pstk pbase) rs ms t rs' ms' /\
- callstack_invariant ((parent, pstk, pbase) :: cs) mm' ms'.
-
-Lemma exec_function_equiv:
- forall f parent rs mm t rs' mm',
- Machabstr.exec_function ge f parent rs mm t rs' mm' ->
- exec_function_prop f parent rs mm t rs' mm'.
-Proof.
- apply (Machabstr.exec_function_ind4 ge
- exec_instr_prop
- exec_instrs_prop
- exec_function_body_prop
- exec_function_prop);
- intros; red; intros.
-
- (* Mlabel *)
- exists ms. split. constructor. auto.
- (* Mgetstack *)
- exists ms. split.
- constructor. rewrite SP. eapply callstack_get_slot; eauto.
- apply wt_get_slot with fr (Int.signed ofs); auto.
- auto.
- (* Msetstack *)
- generalize (wt_function_instrs f WTF _ (INCL _ (in_eq _ _))).
- intro WTI. inversion WTI.
- assert (4 <= Int.signed ofs). omega.
- generalize (callstack_set_slot _ _ _ _ _ _ _ _ _ _ CSI H H5).
- intros [ms' [STO CSI']].
- exists ms'. split. constructor. rewrite SP. auto. auto.
- (* Mgetparam *)
- exists ms. split.
- assert (WTV: Val.has_type v ty). eapply wt_get_slot; eauto.
- generalize (callstack_get_parent _ _ _ _ _ _ _ _ _ _ _ _
- CSI H WTV).
- intros [L1 L2].
- eapply exec_Mgetparam. rewrite SP; eexact L1. eexact L2.
- auto.
- (* Mop *)
- exists ms. split. constructor. auto. auto.
- (* Mload *)
- exists ms. split. econstructor. eauto. eapply callstack_load; eauto.
- auto.
- (* Mstore *)
- generalize (callstack_store _ _ _ _ _ _ _ CSI H0).
- intros [ms' [STO CSI']].
- exists ms'. split. econstructor. eauto. auto.
- auto.
- (* Mcall *)
- red in H1.
- assert (WTF': wt_fundef f').
- destruct ros; simpl in H.
- apply (Genv.find_funct_prop wt_fundef wt_p H).
- destruct (Genv.find_symbol ge i); try discriminate.
- apply (Genv.find_funct_ptr_prop wt_fundef wt_p H).
- generalize (H1 _ _ _ _ WTF' WTRS WTFR CSI).
- intros [ms' [EXF CSI']].
- exists ms'. split. apply exec_Mcall with f'; auto.
- rewrite SP. auto.
- auto.
- (* Malloc *)
- generalize (callstack_alloc _ _ _ _ _ _ _ CSI H0).
- intros [ms' [ALLOC' CSI']].
- exists ms'; split.
- eapply exec_Malloc; eauto.
- auto.
- (* Mgoto *)
- exists ms. split. constructor; auto. auto.
- (* Mcond *)
- exists ms. split. apply exec_Mcond_true; auto. auto.
- exists ms. split. apply exec_Mcond_false; auto. auto.
-
- (* refl *)
- exists ms. split. apply exec_refl. auto.
- (* one *)
- generalize (H0 _ _ _ _ _ _ WTF INCL WTRS WTFR WTPA CSI SP).
- intros [ms' [EX CSI']].
- exists ms'. split. apply exec_one; auto. auto.
- (* trans *)
- generalize (subject_reduction_instrs p wt_p
- _ _ _ _ _ _ _ _ _ _ _ _ H WTF INCL WTRS WTFR WTPA).
- intros [INCL2 [WTRS2 WTFR2]].
- generalize (H0 _ _ _ _ _ _ WTF INCL WTRS WTFR WTPA CSI SP).
- intros [ms1 [EX1 CSI1]].
- generalize (H2 _ _ _ _ _ _ WTF INCL2 WTRS2 WTFR2 WTPA CSI1 SP).
- intros [ms2 [EX2 CSI2]].
- exists ms2. split. eapply exec_trans; eauto. auto.
-
- (* function body *)
- caseEq (alloc ms (- f.(fn_framesize))
- (align_16_top (- f.(fn_framesize)) f.(fn_stacksize))).
- intros ms1 stk1 ALL.
- subst link.
- assert (FS: f.(fn_framesize) >= 0).
- generalize (wt_function_framesize f WTF). omega.
- generalize (callstack_function_entry _ _ _ _ _ _ _ _ _ _ _ _
- CSI H ALL FS
- (wt_function_no_overflow f WTF) H0).
- intros [ms2 [STORELINK [CSI2 EQ]]].
- subst stk1.
- assert (ZERO: Int.signed (Int.repr 0) = 0). reflexivity.
- assert (TWELVE: Int.signed (Int.repr 12) = 12). reflexivity.
- assert (BND: 4 <= Int.signed (Int.repr 12)).
- rewrite TWELVE; omega.
- rewrite <- TWELVE in H1.
- generalize (callstack_set_slot _ _ _ _ _ _ _ _ _ _
- CSI2 H1 BND).
- intros [ms3 [STORERA CSI3]].
- assert (WTFR2: wt_frame fr2).
- eapply wt_set_slot; eauto. eapply wt_set_slot; eauto.
- red. intros. simpl. auto.
- exact I.
- red in H3.
- generalize (H3 _ _ _ _ _ _ WTF (incl_refl _) WTRS WTFR2 WTPA
- CSI3 (refl_equal _)).
- intros [ms4 [EXEC CSI4]].
- generalize (exec_instrs_link_invariant _ _ _ _ _ _ _ _ _ _ _ _ _
- H2 WTF (incl_refl _)).
- intros [INCL LINKINV].
- exists (free ms4 stk). split.
- eapply exec_funct_body; eauto.
- eapply callstack_get_slot. eexact CSI4.
- apply LINKINV. rewrite ZERO. omega.
- eapply slot_gso; eauto. rewrite ZERO. eapply slot_gss; eauto.
- exact I.
- eapply callstack_get_slot. eexact CSI4.
- apply LINKINV. rewrite TWELVE. omega. eapply slot_gss; eauto. auto.
- eapply callstack_function_return; eauto.
-
- (* internal function *)
- inversion WTF. subst f0.
- generalize (H0 (Vptr pstk pbase) Vzero I I
- ms pstk pbase cs H2 WTRS WTPA I (refl_equal _) CSI).
- intros [ms' [EXEC CSI']].
- exists ms'. split. constructor. intros.
- generalize (H0 (Vptr pstk pbase) ra I H1
- ms pstk pbase cs H2 WTRS WTPA H1 (refl_equal _) CSI).
- intros [ms1 [EXEC1 CSI1]].
- rewrite (callstack_exten _ _ _ _ CSI' CSI1). auto.
- auto.
-
- (* external function *)
- exists ms; split. econstructor; eauto.
- eapply transl_extcall_arguments; eauto.
- auto.
-Qed.
-
-End SIMULATION.
-
-Theorem exec_program_equiv:
- forall p t r,
- wt_program p ->
- Machabstr.exec_program p t r ->
- Mach.exec_program p t r.
-Proof.
- intros p t r WTP [fptr [f [rs [mm [FINDPTR [FINDF [EXEC RES]]]]]]].
- assert (WTF: wt_fundef f).
- apply (Genv.find_funct_ptr_prop wt_fundef WTP FINDF).
- assert (WTRS: wt_regset (Regmap.init Vundef)).
- red; intros. rewrite Regmap.gi; simpl; auto.
- assert (WTFR: wt_frame empty_frame).
- red; intros. simpl. auto.
- generalize (exec_function_equiv p WTP
- f empty_frame
- (Regmap.init Vundef) (Genv.init_mem p) t rs mm
- EXEC (Genv.init_mem p) nullptr Int.zero nil
- WTF WTRS WTFR (callstack_init p)).
- intros [ms' [EXEC' CSI]].
- red. exists fptr; exists f; exists rs; exists ms'. tauto.
-Qed.
diff --git a/backend/Machconcr.v b/backend/Machconcr.v
new file mode 100644
index 0000000..fe9a7d9
--- /dev/null
+++ b/backend/Machconcr.v
@@ -0,0 +1,250 @@
+(** The Mach intermediate language: concrete semantics. *)
+
+Require Import Coqlib.
+Require Import Maps.
+Require Import AST.
+Require Import Integers.
+Require Import Values.
+Require Import Mem.
+Require Import Events.
+Require Import Globalenvs.
+Require Import Smallstep.
+Require Import Op.
+Require Import Locations.
+Require Conventions.
+Require Import Mach.
+Require PPCgenretaddr.
+
+(** In the concrete semantics for Mach, the three stack-related Mach
+ instructions are interpreted as memory accesses relative to the
+ stack pointer. More precisely:
+- [Mgetstack ofs ty r] is a memory load at offset [ofs * 4] relative
+ to the stack pointer.
+- [Msetstack r ofs ty] is a memory store at offset [ofs * 4] relative
+ to the stack pointer.
+- [Mgetparam ofs ty r] is a memory load at offset [ofs * 4]
+ relative to the pointer found at offset 0 from the stack pointer.
+ The semantics maintain a linked structure of activation records,
+ with the current record containing a pointer to the record of the
+ caller function at offset 0.
+
+In addition to this linking of activation records, the concrete
+semantics also make provisions for storing a return address
+at offset 12 from the stack pointer. This stack location will
+be used by the PPC code generated by [PPCgen] to save the return
+address into the caller at the beginning of a function, then restore
+it and jump to it at the end of a function. The Mach concrete
+semantics does not attach any particular meaning to the pointer
+stored in this reserved location, but makes sure that it is preserved
+during execution of a function. The [return_address_offset] predicate
+from module [PPCgenretaddr] is used to guess the value of the return
+address that the PPC code generated later will store in the
+reserved location.
+*)
+
+Definition chunk_of_type (ty: typ) :=
+ match ty with Tint => Mint32 | Tfloat => Mfloat64 end.
+
+Definition load_stack (m: mem) (sp: val) (ty: typ) (ofs: int) :=
+ Mem.loadv (chunk_of_type ty) m (Val.add sp (Vint ofs)).
+
+Definition store_stack (m: mem) (sp: val) (ty: typ) (ofs: int) (v: val) :=
+ Mem.storev (chunk_of_type ty) m (Val.add sp (Vint ofs)) v.
+
+(** Extract the values of the arguments of an external call. *)
+
+Inductive extcall_arg: regset -> mem -> val -> loc -> val -> Prop :=
+ | extcall_arg_reg: forall rs m sp r,
+ extcall_arg rs m sp (R r) (rs r)
+ | extcall_arg_stack: forall rs m sp ofs ty v,
+ load_stack m sp ty (Int.repr (4 * ofs)) = Some v ->
+ extcall_arg rs m sp (S (Outgoing ofs ty)) v.
+
+Inductive extcall_args: regset -> mem -> val -> list loc -> list val -> Prop :=
+ | extcall_args_nil: forall rs m sp,
+ extcall_args rs m sp nil nil
+ | extcall_args_cons: forall rs m sp l1 ll v1 vl,
+ extcall_arg rs m sp l1 v1 -> extcall_args rs m sp ll vl ->
+ extcall_args rs m sp (l1 :: ll) (v1 :: vl).
+
+Definition extcall_arguments
+ (rs: regset) (m: mem) (sp: val) (sg: signature) (args: list val) : Prop :=
+ extcall_args rs m sp (Conventions.loc_arguments sg) args.
+
+(** The components of an execution state are:
+
+- [State cs f sp c rs m]: [f] is the block reference corresponding
+ to the function currently executing. [sp] is the stack pointer.
+ [c] is the list of instructions that remain to be executed.
+ [rs] assigns values to registers. [m] is the memory state.
+- [Callstate cs f rs m]: [f] is the block reference corresponding
+ to the function being called. [rs] is the current values of registers,
+ and [m] the current memory state.
+- [Returnstate cs rs m]: [rs] is the current values of registers,
+ and [m] the current memory state.
+
+[cs] is a list of stack frames [Stackframe f sp retaddr c],
+where [f] is the block reference for the calling function,
+[c] the code within this function that follows the call instruction,
+[sp] its stack pointer, and [retaddr] the return address predicted
+by [PPCgenretaddr.return_address_offset].
+*)
+
+Inductive stackframe: Set :=
+ | Stackframe:
+ forall (f: block) (sp retaddr: val) (c: code),
+ stackframe.
+
+Inductive state: Set :=
+ | State:
+ forall (stack: list stackframe) (f: block) (sp: val)
+ (c: code) (rs: regset) (m: mem),
+ state
+ | Callstate:
+ forall (stack: list stackframe) (f: block) (rs: regset) (m: mem),
+ state
+ | Returnstate:
+ forall (stack: list stackframe) (rs: regset) (m: mem),
+ state.
+
+Definition parent_sp (s: list stackframe) : val :=
+ match s with
+ | nil => Vptr Mem.nullptr Int.zero
+ | Stackframe f sp ra c :: s' => sp
+ end.
+
+Definition parent_ra (s: list stackframe) : val :=
+ match s with
+ | nil => Vzero
+ | Stackframe f sp ra c :: s' => ra
+ end.
+
+Section RELSEM.
+
+Variable ge: genv.
+
+Inductive step: state -> trace -> state -> Prop :=
+ | exec_Mlabel:
+ forall s f sp lbl c rs m,
+ step (State s f sp (Mlabel lbl :: c) rs m)
+ E0 (State s f sp c rs m)
+ | exec_Mgetstack:
+ forall s f sp ofs ty dst c rs m v,
+ load_stack m sp ty ofs = Some v ->
+ step (State s f sp (Mgetstack ofs ty dst :: c) rs m)
+ E0 (State s f sp c (rs#dst <- v) m)
+ | exec_Msetstack:
+ forall s f sp src ofs ty c rs m m',
+ store_stack m sp ty ofs (rs src) = Some m' ->
+ step (State s f sp (Msetstack src ofs ty :: c) rs m)
+ E0 (State s f sp c rs m')
+ | exec_Mgetparam:
+ forall s f sp parent ofs ty dst c rs m v,
+ load_stack m sp Tint (Int.repr 0) = Some parent ->
+ load_stack m parent ty ofs = Some v ->
+ step (State s f sp (Mgetparam ofs ty dst :: c) rs m)
+ E0 (State s f sp c (rs#dst <- v) m)
+ | exec_Mop:
+ forall s f sp op args res c rs m v,
+ eval_operation ge sp op rs##args m = Some v ->
+ step (State s f sp (Mop op args res :: c) rs m)
+ E0 (State s f sp c (rs#res <- v) m)
+ | exec_Mload:
+ forall s f sp chunk addr args dst c rs m a v,
+ eval_addressing ge sp addr rs##args = Some a ->
+ Mem.loadv chunk m a = Some v ->
+ step (State s f sp (Mload chunk addr args dst :: c) rs m)
+ E0 (State s f sp c (rs#dst <- v) m)
+ | exec_Mstore:
+ forall s f sp chunk addr args src c rs m m' a,
+ eval_addressing ge sp addr rs##args = Some a ->
+ Mem.storev chunk m a (rs src) = Some m' ->
+ step (State s f sp (Mstore chunk addr args src :: c) rs m)
+ E0 (State s f sp c rs m')
+ | exec_Mcall:
+ forall s fb sp sig ros c rs m f f' ra,
+ find_function_ptr ge ros rs = Some f' ->
+ Genv.find_funct_ptr ge fb = Some (Internal f) ->
+ PPCgenretaddr.return_address_offset f c ra ->
+ step (State s fb sp (Mcall sig ros :: c) rs m)
+ E0 (Callstate (Stackframe fb sp (Vptr fb ra) c :: s)
+ f' rs m)
+ | exec_Mtailcall:
+ forall s fb stk soff sig ros c rs m f',
+ find_function_ptr ge ros rs = Some f' ->
+ load_stack m (Vptr stk soff) Tint (Int.repr 0) = Some (parent_sp s) ->
+ load_stack m (Vptr stk soff) Tint (Int.repr 12) = Some (parent_ra s) ->
+ step (State s fb (Vptr stk soff) (Mtailcall sig ros :: c) rs m)
+ E0 (Callstate s f' rs (Mem.free m stk))
+ | exec_Malloc:
+ forall s f sp c rs m sz m' blk,
+ rs (Conventions.loc_alloc_argument) = Vint sz ->
+ Mem.alloc m 0 (Int.signed sz) = (m', blk) ->
+ step (State s f sp (Malloc :: c) rs m)
+ E0 (State s f sp c
+ (rs#Conventions.loc_alloc_result <- (Vptr blk Int.zero))
+ m')
+ | exec_Mgoto:
+ forall s fb f sp lbl c rs m c',
+ Genv.find_funct_ptr ge fb = Some (Internal f) ->
+ find_label lbl f.(fn_code) = Some c' ->
+ step (State s fb sp (Mgoto lbl :: c) rs m)
+ E0 (State s fb sp c' rs m)
+ | exec_Mcond_true:
+ forall s fb f sp cond args lbl c rs m c',
+ eval_condition cond rs##args m = Some true ->
+ Genv.find_funct_ptr ge fb = Some (Internal f) ->
+ find_label lbl f.(fn_code) = Some c' ->
+ step (State s fb sp (Mcond cond args lbl :: c) rs m)
+ E0 (State s fb sp c' rs m)
+ | exec_Mcond_false:
+ forall s f sp cond args lbl c rs m,
+ eval_condition cond rs##args m = Some false ->
+ step (State s f sp (Mcond cond args lbl :: c) rs m)
+ E0 (State s f sp c rs m)
+ | exec_Mreturn:
+ forall s f stk soff c rs m,
+ load_stack m (Vptr stk soff) Tint (Int.repr 0) = Some (parent_sp s) ->
+ load_stack m (Vptr stk soff) Tint (Int.repr 12) = Some (parent_ra s) ->
+ step (State s f (Vptr stk soff) (Mreturn :: c) rs m)
+ E0 (Returnstate s rs (Mem.free m stk))
+ | exec_function_internal:
+ forall s fb rs m f m1 m2 m3 stk,
+ Genv.find_funct_ptr ge fb = Some (Internal f) ->
+ Mem.alloc m (- f.(fn_framesize))
+ (align_16_top (- f.(fn_framesize)) f.(fn_stacksize))
+ = (m1, stk) ->
+ let sp := Vptr stk (Int.repr (-f.(fn_framesize))) in
+ store_stack m1 sp Tint (Int.repr 0) (parent_sp s) = Some m2 ->
+ store_stack m2 sp Tint (Int.repr 12) (parent_ra s) = Some m3 ->
+ step (Callstate s fb rs m)
+ E0 (State s fb sp f.(fn_code) rs m3)
+ | exec_function_external:
+ forall s fb rs m t rs' ef args res,
+ Genv.find_funct_ptr ge fb = Some (External ef) ->
+ event_match ef args t res ->
+ extcall_arguments rs m (parent_sp s) ef.(ef_sig) args ->
+ rs' = (rs#(Conventions.loc_result ef.(ef_sig)) <- res) ->
+ step (Callstate s fb rs m)
+ t (Returnstate s rs' m)
+ | exec_return:
+ forall s f sp ra c rs m,
+ step (Returnstate (Stackframe f sp ra c :: s) rs m)
+ E0 (State s f sp c rs m).
+
+End RELSEM.
+
+Inductive initial_state (p: program): state -> Prop :=
+ | initial_state_intro: forall fb,
+ let ge := Genv.globalenv p in
+ let m0 := Genv.init_mem p in
+ Genv.find_symbol ge p.(prog_main) = Some fb ->
+ initial_state p (Callstate nil fb (Regmap.init Vundef) m0).
+
+Inductive final_state: state -> int -> Prop :=
+ | final_state_intro: forall rs m r,
+ rs R3 = Vint r ->
+ final_state (Returnstate nil rs m) r.
+
+Definition exec_program (p: program) (beh: program_behavior) : Prop :=
+ program_behaves step (initial_state p) final_state (Genv.globalenv p) beh.
diff --git a/backend/Machtyping.v b/backend/Machtyping.v
index ad3ee88..28037ce 100644
--- a/backend/Machtyping.v
+++ b/backend/Machtyping.v
@@ -26,7 +26,7 @@ Inductive wt_instr : instruction -> Prop :=
wt_instr (Mgetstack ofs ty r)
| wt_Msetstack:
forall ofs ty r,
- mreg_type r = ty -> 24 <= Int.signed ofs ->
+ mreg_type r = ty ->
wt_instr (Msetstack r ofs ty)
| wt_Mgetparam:
forall ofs ty r,
@@ -36,12 +36,9 @@ Inductive wt_instr : instruction -> Prop :=
forall r1 r,
mreg_type r1 = mreg_type r ->
wt_instr (Mop Omove (r1 :: nil) r)
- | wt_Mopundef:
- forall r,
- wt_instr (Mop Oundef nil r)
| wt_Mop:
forall op args res,
- op <> Omove -> op <> Oundef ->
+ op <> Omove ->
(List.map mreg_type args, mreg_type res) = type_of_operation op ->
wt_instr (Mop op args res)
| wt_Mload:
@@ -58,6 +55,11 @@ Inductive wt_instr : instruction -> Prop :=
forall sig ros,
match ros with inl r => mreg_type r = Tint | inr s => True end ->
wt_instr (Mcall sig ros)
+ | wt_Mtailcall:
+ forall sig ros,
+ Conventions.tailcall_possible sig ->
+ match ros with inl r => mreg_type r = Tint | inr s => True end ->
+ wt_instr (Mtailcall sig ros)
| wt_Malloc:
wt_instr Malloc
| wt_Mgoto:
@@ -95,27 +97,20 @@ Definition wt_program (p: program) : Prop :=
Require Import Machabstr.
-(** We show a weak type soundness result for the alternate semantics
+(** We show a weak type soundness result for the abstract semantics
of Mach: for a well-typed Mach program, if a transition is taken
from a state where registers hold values of their static types,
registers in the final state hold values of their static types
as well. This is a subject reduction theorem for our type system.
It is used in the proof of implication from the abstract Mach
- semantics to the concrete Mach semantics (file [Machabstr2mach]).
+ semantics to the concrete Mach semantics (file [Machabstr2concr]).
*)
Definition wt_regset (rs: regset) : Prop :=
forall r, Val.has_type (rs r) (mreg_type r).
-Definition wt_content (c: content) : Prop :=
- match c with
- | Datum32 v => Val.has_type v Tint
- | Datum64 v => Val.has_type v Tfloat
- | _ => True
- end.
-
Definition wt_frame (fr: frame) : Prop :=
- forall ofs, wt_content (fr.(contents) ofs).
+ forall ty ofs, Val.has_type (fr.(fr_contents) ty ofs) ty.
Lemma wt_setreg:
forall (rs: regset) (r: mreg) (v: val),
@@ -134,17 +129,8 @@ Lemma wt_get_slot:
wt_frame fr ->
Val.has_type v ty.
Proof.
- induction 1; intro. subst v.
- set (pos := low fr + ofs).
- case ty; simpl.
- unfold getN. case (check_cont 3 (pos + 1) (contents fr)).
- generalize (H2 pos). unfold wt_content.
- destruct (contents fr pos); simpl; tauto.
- simpl; auto.
- unfold getN. case (check_cont 7 (pos + 1) (contents fr)).
- generalize (H2 pos). unfold wt_content.
- destruct (contents fr pos); simpl; tauto.
- simpl; auto.
+ induction 1; intros.
+ subst v. apply H2.
Qed.
Lemma wt_set_slot:
@@ -154,43 +140,37 @@ Lemma wt_set_slot:
Val.has_type v ty ->
wt_frame fr'.
Proof.
- intros. induction H.
- set (i := low fr + ofs).
- red; intro j; simpl.
- assert (forall n ofs c,
- let c' := set_cont n ofs c in
- forall k, c' k = c k \/ c' k = Cont).
- induction n; simpl; intros.
- left; auto.
- unfold update. case (zeq k ofs0); intro.
- right; auto.
- apply IHn.
- destruct ty; simpl; unfold store_contents; unfold setN;
- unfold update; case (zeq j i); intro.
- red. assumption.
- elim (H 3%nat (i + 1) (contents fr) j); intro; rewrite H2.
- apply H0. red; auto.
- red. assumption.
- elim (H 7%nat (i + 1) (contents fr) j); intro; rewrite H2.
- apply H0. red; auto.
+ intros. induction H. subst fr'; red; intros; simpl.
+ destruct (zeq (fr_low fr + ofs) ofs0).
+ destruct (typ_eq ty ty0). congruence. exact I.
+ destruct (zle (ofs0 + AST.typesize ty0) (fr_low fr + ofs)).
+ apply H0.
+ destruct (zle (fr_low fr + ofs + AST.typesize ty) ofs0).
+ apply H0.
+ exact I.
+Qed.
+
+Lemma wt_empty_frame:
+ wt_frame empty_frame.
+Proof.
+ intros; red; intros; exact I.
Qed.
Lemma wt_init_frame:
forall f,
wt_frame (init_frame f).
Proof.
- intros. unfold init_frame.
- red; intros. simpl. exact I.
+ intros; red; intros; exact I.
Qed.
-Lemma incl_find_label:
- forall lbl c c', find_label lbl c = Some c' -> incl c' c.
+Lemma is_tail_find_label:
+ forall lbl c c', find_label lbl c = Some c' -> is_tail c' c.
Proof.
induction c; simpl.
intros; discriminate.
case (is_label lbl a); intros.
- injection H; intro; subst c'; apply incl_tl; apply incl_refl.
- apply incl_tl; auto.
+ injection H; intro; subst c'. constructor. constructor.
+ constructor; auto.
Qed.
Lemma wt_event_match:
@@ -203,193 +183,115 @@ Qed.
Section SUBJECT_REDUCTION.
+Inductive wt_stackframe: stackframe -> Prop :=
+ | wt_stackframe_intro: forall f sp c fr,
+ wt_function f ->
+ Val.has_type sp Tint ->
+ is_tail c f.(fn_code) ->
+ wt_frame fr ->
+ wt_stackframe (Stackframe f sp c fr).
+
+Inductive wt_state: state -> Prop :=
+ | wt_state_intro: forall stk f sp c rs fr m
+ (STK: forall s, In s stk -> wt_stackframe s)
+ (WTF: wt_function f)
+ (WTSP: Val.has_type sp Tint)
+ (TAIL: is_tail c f.(fn_code))
+ (WTRS: wt_regset rs)
+ (WTFR: wt_frame fr),
+ wt_state (State stk f sp c rs fr m)
+ | wt_state_call: forall stk f rs m,
+ (forall s, In s stk -> wt_stackframe s) ->
+ wt_fundef f ->
+ wt_regset rs ->
+ wt_state (Callstate stk f rs m)
+ | wt_state_return: forall stk rs m,
+ (forall s, In s stk -> wt_stackframe s) ->
+ wt_regset rs ->
+ wt_state (Returnstate stk rs m).
+
Variable p: program.
Hypothesis wt_p: wt_program p.
Let ge := Genv.globalenv p.
-Definition exec_instr_prop
- (f: function) (sp: val) (parent: frame)
- (c1: code) (rs1: regset) (fr1: frame) (m1: mem) (t: trace)
- (c2: code) (rs2: regset) (fr2: frame) (m2: mem) :=
- forall (WTF: wt_function f)
- (INCL: incl c1 f.(fn_code))
- (WTRS: wt_regset rs1)
- (WTFR: wt_frame fr1)
- (WTPA: wt_frame parent),
- incl c2 f.(fn_code) /\ wt_regset rs2 /\ wt_frame fr2.
-Definition exec_function_body_prop
- (f: function) (parent: frame) (link ra: val)
- (rs1: regset) (m1: mem) (t: trace) (rs2: regset) (m2: mem) :=
- forall (WTF: wt_function f)
- (WTRS: wt_regset rs1)
- (WTPA: wt_frame parent)
- (WTLINK: Val.has_type link Tint)
- (WTRA: Val.has_type ra Tint),
- wt_regset rs2.
-Definition exec_function_prop
- (f: fundef) (parent: frame)
- (rs1: regset) (m1: mem) (t: trace) (rs2: regset) (m2: mem) :=
- forall (WTF: wt_fundef f)
- (WTRS: wt_regset rs1)
- (WTPA: wt_frame parent),
- wt_regset rs2.
-
Lemma subject_reduction:
- (forall f sp parent c1 rs1 fr1 m1 t c2 rs2 fr2 m2,
- exec_instr ge f sp parent c1 rs1 fr1 m1 t c2 rs2 fr2 m2 ->
- exec_instr_prop f sp parent c1 rs1 fr1 m1 t c2 rs2 fr2 m2)
-/\ (forall f sp parent c1 rs1 fr1 m1 t c2 rs2 fr2 m2,
- exec_instrs ge f sp parent c1 rs1 fr1 m1 t c2 rs2 fr2 m2 ->
- exec_instr_prop f sp parent c1 rs1 fr1 m1 t c2 rs2 fr2 m2)
-/\ (forall f parent link ra rs1 m1 t rs2 m2,
- exec_function_body ge f parent link ra rs1 m1 t rs2 m2 ->
- exec_function_body_prop f parent link ra rs1 m1 t rs2 m2)
-/\ (forall f parent rs1 m1 t rs2 m2,
- exec_function ge f parent rs1 m1 t rs2 m2 ->
- exec_function_prop f parent rs1 m1 t rs2 m2).
+ forall s1 t s2, step ge s1 t s2 ->
+ forall (WTS: wt_state s1), wt_state s2.
Proof.
- apply exec_mutual_induction; red; intros;
- try (generalize (wt_function_instrs _ WTF _ (INCL _ (in_eq _ _))); intro;
- intuition eauto with coqlib).
+ induction 1; intros; inv WTS;
+ try (generalize (wt_function_instrs _ WTF _ (is_tail_in TAIL)); intro;
+ eapply wt_state_intro; eauto with coqlib).
apply wt_setreg; auto.
inversion H0. rewrite H2. apply wt_get_slot with fr (Int.signed ofs); auto.
inversion H0. eapply wt_set_slot; eauto.
- rewrite <- H3. apply WTRS.
+ rewrite <- H2. apply WTRS.
+ assert (wt_frame (parent_frame s)).
+ destruct s; simpl. apply wt_empty_frame.
+ generalize (STK s (in_eq _ _)); intro. inv H1. auto.
inversion H0. apply wt_setreg; auto.
- rewrite H2. apply wt_get_slot with parent (Int.signed ofs); auto.
+ rewrite H3. apply wt_get_slot with (parent_frame s) (Int.signed ofs); auto.
- apply wt_setreg; auto. inversion H0.
- simpl. subst args; subst op. simpl in H.
+ apply wt_setreg; auto. inv H0.
+ simpl in H.
rewrite <- H2. replace v with (rs r1). apply WTRS. congruence.
- subst args; subst op. simpl in H.
- replace v with Vundef. simpl; auto. congruence.
replace (mreg_type res) with (snd (type_of_operation op)).
- apply type_of_operation_sound with fundef ge rs##args sp; auto.
- rewrite <- H6; reflexivity.
+ apply type_of_operation_sound with fundef ge rs##args sp m; auto.
+ rewrite <- H5; reflexivity.
apply wt_setreg; auto. inversion H1. rewrite H7.
eapply type_of_chunk_correct; eauto.
- apply H1; auto.
- destruct ros; simpl in H.
- apply (Genv.find_funct_prop wt_fundef wt_p H).
- destruct (Genv.find_symbol ge i).
- apply (Genv.find_funct_ptr_prop wt_fundef wt_p H).
- discriminate.
+ assert (WTFD: wt_fundef f').
+ destruct ros; simpl in H.
+ apply (Genv.find_funct_prop wt_fundef wt_p H).
+ destruct (Genv.find_symbol ge i); try discriminate.
+ apply (Genv.find_funct_ptr_prop wt_fundef wt_p H).
+ econstructor; eauto.
+ intros. elim H0; intro. subst s0. econstructor; eauto with coqlib.
+ auto.
+
+ assert (WTFD: wt_fundef f').
+ destruct ros; simpl in H.
+ apply (Genv.find_funct_prop wt_fundef wt_p H).
+ destruct (Genv.find_symbol ge i); try discriminate.
+ apply (Genv.find_funct_ptr_prop wt_fundef wt_p H).
+ econstructor; eauto.
apply wt_setreg; auto. exact I.
- apply incl_find_label with lbl; auto.
- apply incl_find_label with lbl; auto.
+ apply is_tail_find_label with lbl; congruence.
+ apply is_tail_find_label with lbl; congruence.
- tauto.
- apply H0; auto.
- generalize (H0 WTF INCL WTRS WTFR WTPA). intros [A [B C]].
- apply H2; auto.
+ econstructor; eauto.
- assert (WTFR2: wt_frame fr2).
- eapply wt_set_slot; eauto.
- eapply wt_set_slot; eauto.
- apply wt_init_frame.
- generalize (H3 WTF (incl_refl _) WTRS WTFR2 WTPA).
- tauto.
+ econstructor; eauto with coqlib. inv H5; auto. exact I.
+ apply wt_init_frame.
- apply (H0 Vzero Vzero). exact I. exact I.
- inversion WTF; auto. auto. auto.
- exact I. exact I.
-
- rewrite H1. apply wt_setreg; auto.
+ econstructor; eauto. apply wt_setreg; auto.
generalize (wt_event_match _ _ _ _ H).
unfold proj_sig_res, Conventions.loc_result.
destruct (sig_res (ef_sig ef)).
- destruct t; simpl; auto.
+ destruct t0; simpl; auto.
simpl; auto.
-Qed.
-
-Lemma subject_reduction_instr:
- forall f sp parent c1 rs1 fr1 m1 t c2 rs2 fr2 m2,
- exec_instr ge f sp parent c1 rs1 fr1 m1 t c2 rs2 fr2 m2 ->
- exec_instr_prop f sp parent c1 rs1 fr1 m1 t c2 rs2 fr2 m2.
-Proof (proj1 subject_reduction).
-
-Lemma subject_reduction_instrs:
- forall f sp parent c1 rs1 fr1 m1 t c2 rs2 fr2 m2,
- exec_instrs ge f sp parent c1 rs1 fr1 m1 t c2 rs2 fr2 m2 ->
- exec_instr_prop f sp parent c1 rs1 fr1 m1 t c2 rs2 fr2 m2.
-Proof (proj1 (proj2 subject_reduction)).
-Lemma subject_reduction_function:
- forall f parent rs1 m1 t rs2 m2,
- exec_function ge f parent rs1 m1 t rs2 m2 ->
- exec_function_prop f parent rs1 m1 t rs2 m2.
-Proof (proj2 (proj2 (proj2 subject_reduction))).
-
-End SUBJECT_REDUCTION.
-
-(** * Preservation of the reserved frame slots during execution *)
-
-(** We now show another result useful for the proof of implication
- between the two Mach semantics: well-typed functions do not
- change the values of the back link and return address fields
- of the frame slot (at offsets 0 and 12) during their execution.
- Actually, we show that the whole reserved part of the frame
- (between offsets 0 and 24) does not change. *)
-
-Definition link_invariant (fr1 fr2: frame) : Prop :=
- forall pos v,
- 0 <= pos < 20 ->
- get_slot fr1 Tint pos v -> get_slot fr2 Tint pos v.
-
-Remark link_invariant_refl:
- forall fr, link_invariant fr fr.
-Proof.
- intros; red; auto.
+ generalize (H1 _ (in_eq _ _)); intro. inv H.
+ econstructor; eauto.
+ eauto with coqlib.
Qed.
-
-Lemma set_slot_link_invariant:
- forall fr ty ofs v fr',
- set_slot fr ty ofs v fr' ->
- 24 <= ofs ->
- link_invariant fr fr'.
-Proof.
- induction 1. intros; red; intros.
- inversion H1. constructor. auto. exact H3.
- simpl contents. simpl low. symmetry. rewrite H4.
- apply load_store_contents_other. simpl. simpl in H3.
- omega.
-Qed.
-
-Lemma exec_instr_link_invariant:
- forall ge f sp parent c1 rs1 fr1 m1 t c2 rs2 fr2 m2,
- exec_instr ge f sp parent c1 rs1 fr1 m1 t c2 rs2 fr2 m2 ->
- wt_function f ->
- incl c1 f.(fn_code) ->
- incl c2 f.(fn_code) /\ link_invariant fr1 fr2.
-Proof.
- induction 1; intros;
- (split; [eauto with coqlib | try (apply link_invariant_refl)]).
- eapply set_slot_link_invariant; eauto.
- generalize (wt_function_instrs _ H0 _ (H1 _ (in_eq _ _))); intro.
- inversion H2. auto.
- eapply incl_find_label; eauto.
- eapply incl_find_label; eauto.
-Qed.
-
-Lemma exec_instrs_link_invariant:
- forall ge f sp parent c1 rs1 fr1 m1 t c2 rs2 fr2 m2,
- exec_instrs ge f sp parent c1 rs1 fr1 m1 t c2 rs2 fr2 m2 ->
- wt_function f ->
- incl c1 f.(fn_code) ->
- incl c2 f.(fn_code) /\ link_invariant fr1 fr2.
+(*
+Lemma subject_reduction_2:
+ forall s1 t s2, step ge s1 t s2 ->
+ forall (WTS: wt_state s1), wt_state s2.
Proof.
induction 1; intros.
- split. auto. apply link_invariant_refl.
- eapply exec_instr_link_invariant; eauto.
- generalize (IHexec_instrs1 H2 H3); intros [A B].
- generalize (IHexec_instrs2 H2 A); intros [C D].
- split. auto. red; auto.
+ auto.
+ eapply subject_reduction; eauto.
+ auto.
Qed.
+*)
+
+End SUBJECT_REDUCTION.
diff --git a/backend/Op.v b/backend/Op.v
index efd0d9c..698b433 100644
--- a/backend/Op.v
+++ b/backend/Op.v
@@ -1,5 +1,5 @@
(** Operators and addressing modes. The abstract syntax and dynamic
- semantics for the Cminor, RTL, LTL and Mach languages depend on the
+ semantics for the CminorSel, RTL, LTL and Mach languages depend on the
following types, defined in this library:
- [condition]: boolean conditions for conditional branches;
- [operation]: arithmetic and logical operations;
@@ -9,7 +9,7 @@
processor can compute in one instruction. In other terms, these
types reflect the state of the program after instruction selection.
For a processor-independent set of operations, see the abstract
- syntax and dynamic semantics of the Csharpminor input language.
+ syntax and dynamic semantics of the Cminor language.
*)
Require Import Coqlib.
@@ -43,7 +43,6 @@ Inductive operation : Set :=
| Ofloatconst: float -> operation (**r [rd] is set to the given float constant *)
| Oaddrsymbol: ident -> int -> operation (**r [rd] is set to the the address of the symbol plus the offset *)
| Oaddrstack: int -> operation (**r [rd] is set to the stack pointer plus the given offset *)
- | Oundef: operation (**r set [rd] to undefined value *)
(*c Integer arithmetic: *)
| Ocast8signed: operation (**r [rd] is 8-bit sign extension of [r1] *)
| Ocast8unsigned: operation (**r [rd] is 8-bit zero extension of [r1] *)
@@ -110,32 +109,28 @@ Definition eval_compare_null (c: comparison) (n: int) : option bool :=
then match c with Ceq => Some false | Cne => Some true | _ => None end
else None.
-Definition eval_condition (cond: condition) (vl: list val) : option bool :=
+Definition eval_condition (cond: condition) (vl: list val) (m: mem):
+ option bool :=
match cond, vl with
| Ccomp c, Vint n1 :: Vint n2 :: nil =>
Some (Int.cmp c n1 n2)
| Ccomp c, Vptr b1 n1 :: Vptr b2 n2 :: nil =>
- if eq_block b1 b2 then Some (Int.cmp c n1 n2) else None
+ if valid_pointer m b1 (Int.signed n1)
+ && valid_pointer m b2 (Int.signed n2) then
+ if eq_block b1 b2 then Some (Int.cmp c n1 n2) else None
+ else None
| Ccomp c, Vptr b1 n1 :: Vint n2 :: nil =>
eval_compare_null c n2
| Ccomp c, Vint n1 :: Vptr b2 n2 :: nil =>
eval_compare_null c n1
| Ccompu c, Vint n1 :: Vint n2 :: nil =>
Some (Int.cmpu c n1 n2)
- | Ccompu c, Vptr b1 n1 :: Vptr b2 n2 :: nil =>
- if eq_block b1 b2 then Some (Int.cmpu c n1 n2) else None
- | Ccompu c, Vptr b1 n1 :: Vint n2 :: nil =>
- eval_compare_null c n2
- | Ccompu c, Vint n1 :: Vptr b2 n2 :: nil =>
- eval_compare_null c n1
| Ccompimm c n, Vint n1 :: nil =>
Some (Int.cmp c n1 n)
| Ccompimm c n, Vptr b1 n1 :: nil =>
eval_compare_null c n
| Ccompuimm c n, Vint n1 :: nil =>
Some (Int.cmpu c n1 n)
- | Ccompuimm c n, Vptr b1 n1 :: nil =>
- eval_compare_null c n
| Ccompf c, Vfloat f1 :: Vfloat f2 :: nil =>
Some (Float.cmp c f1 f2)
| Cnotcompf c, Vfloat f1 :: Vfloat f2 :: nil =>
@@ -156,7 +151,7 @@ Definition offset_sp (sp: val) (delta: int) : option val :=
Definition eval_operation
(F: Set) (genv: Genv.t F) (sp: val)
- (op: operation) (vl: list val) : option val :=
+ (op: operation) (vl: list val) (m: mem): option val :=
match op, vl with
| Omove, v1::nil => Some v1
| Ointconst n, nil => Some (Vint n)
@@ -167,7 +162,6 @@ Definition eval_operation
| Some b => Some (Vptr b ofs)
end
| Oaddrstack ofs, nil => offset_sp sp ofs
- | Oundef, nil => Some Vundef
| Ocast8signed, v1 :: nil => Some (Val.cast8signed v1)
| Ocast8unsigned, v1 :: nil => Some (Val.cast8unsigned v1)
| Ocast16signed, v1 :: nil => Some (Val.cast16signed v1)
@@ -228,7 +222,7 @@ Definition eval_operation
| Ofloatofintu, Vint n1 :: nil =>
Some (Vfloat (Float.floatofintu n1))
| Ocmp c, _ =>
- match eval_condition c vl with
+ match eval_condition c vl m with
| None => None
| Some false => Some Vfalse
| Some true => Some Vtrue
@@ -297,26 +291,23 @@ Proof.
Qed.
Lemma eval_negate_condition:
- forall (cond: condition) (vl: list val) (b: bool),
- eval_condition cond vl = Some b ->
- eval_condition (negate_condition cond) vl = Some (negb b).
+ forall (cond: condition) (vl: list val) (b: bool) (m: mem),
+ eval_condition cond vl m = Some b ->
+ eval_condition (negate_condition cond) vl m = Some (negb b).
Proof.
intros.
destruct cond; simpl in H; FuncInv; try subst b; simpl.
rewrite Int.negate_cmp. auto.
apply eval_negate_compare_null; auto.
apply eval_negate_compare_null; auto.
+ destruct (valid_pointer m b0 (Int.signed i) &&
+ valid_pointer m b1 (Int.signed i0)).
destruct (eq_block b0 b1). rewrite Int.negate_cmp. congruence.
- discriminate.
+ discriminate. discriminate.
rewrite Int.negate_cmpu. auto.
- apply eval_negate_compare_null; auto.
- apply eval_negate_compare_null; auto.
- destruct (eq_block b0 b1). rewrite Int.negate_cmpu. congruence.
- discriminate.
rewrite Int.negate_cmp. auto.
apply eval_negate_compare_null; auto.
rewrite Int.negate_cmpu. auto.
- apply eval_negate_compare_null; auto.
auto.
rewrite negb_elim. auto.
auto.
@@ -337,8 +328,8 @@ Hypothesis agree_on_symbols:
forall (s: ident), Genv.find_symbol ge2 s = Genv.find_symbol ge1 s.
Lemma eval_operation_preserved:
- forall sp op vl,
- eval_operation ge2 sp op vl = eval_operation ge1 sp op vl.
+ forall sp op vl m,
+ eval_operation ge2 sp op vl m = eval_operation ge1 sp op vl m.
Proof.
intros.
unfold eval_operation; destruct op; try rewrite agree_on_symbols;
@@ -356,6 +347,74 @@ Qed.
End GENV_TRANSF.
+(** [eval_condition] and [eval_operation] depend on a memory store
+ (to check pointer validity in pointer comparisons).
+ We show that their results are preserved by a change of
+ memory if this change preserves pointer validity.
+ In particular, this holds in case of a memory allocation
+ or a memory store. *)
+
+Lemma eval_condition_change_mem:
+ forall m m' c args b,
+ (forall b ofs, valid_pointer m b ofs = true -> valid_pointer m' b ofs = true) ->
+ eval_condition c args m = Some b -> eval_condition c args m' = Some b.
+Proof.
+ intros until b. intro INV. destruct c; simpl; auto.
+ destruct args; auto. destruct v; auto. destruct args; auto.
+ destruct v; auto. destruct args; auto.
+ caseEq (valid_pointer m b0 (Int.signed i)); intro.
+ caseEq (valid_pointer m b1 (Int.signed i0)); intro.
+ simpl. rewrite (INV _ _ H). rewrite (INV _ _ H0). auto.
+ simpl; congruence. simpl; congruence.
+Qed.
+
+Lemma eval_operation_change_mem:
+ forall (F: Set) m m' (ge: Genv.t F) sp op args v,
+ (forall b ofs, valid_pointer m b ofs = true -> valid_pointer m' b ofs = true) ->
+ eval_operation ge sp op args m = Some v -> eval_operation ge sp op args m' = Some v.
+Proof.
+ intros until v; intro INV. destruct op; simpl; auto.
+ caseEq (eval_condition c args m); intros.
+ rewrite (eval_condition_change_mem _ _ _ _ INV H). auto.
+ discriminate.
+Qed.
+
+Lemma eval_condition_alloc:
+ forall m lo hi m' b c args v,
+ Mem.alloc m lo hi = (m', b) ->
+ eval_condition c args m = Some v -> eval_condition c args m' = Some v.
+Proof.
+ intros. apply eval_condition_change_mem with m; auto.
+ intros. eapply valid_pointer_alloc; eauto.
+Qed.
+
+Lemma eval_operation_alloc:
+ forall (F: Set) m lo hi m' b (ge: Genv.t F) sp op args v,
+ Mem.alloc m lo hi = (m', b) ->
+ eval_operation ge sp op args m = Some v -> eval_operation ge sp op args m' = Some v.
+Proof.
+ intros. apply eval_operation_change_mem with m; auto.
+ intros. eapply valid_pointer_alloc; eauto.
+Qed.
+
+Lemma eval_condition_store:
+ forall chunk m b ofs v' m' c args v,
+ Mem.store chunk m b ofs v' = Some m' ->
+ eval_condition c args m = Some v -> eval_condition c args m' = Some v.
+Proof.
+ intros. apply eval_condition_change_mem with m; auto.
+ intros. eapply valid_pointer_store; eauto.
+Qed.
+
+Lemma eval_operation_store:
+ forall (F: Set) chunk m b ofs v' m' (ge: Genv.t F) sp op args v,
+ Mem.store chunk m b ofs v' = Some m' ->
+ eval_operation ge sp op args m = Some v -> eval_operation ge sp op args m' = Some v.
+Proof.
+ intros. apply eval_operation_change_mem with m; auto.
+ intros. eapply valid_pointer_store; eauto.
+Qed.
+
(** Recognition of move operations. *)
Definition is_move_operation
@@ -398,7 +457,6 @@ Definition type_of_operation (op: operation) : list typ * typ :=
| Ofloatconst _ => (nil, Tfloat)
| Oaddrsymbol _ _ => (nil, Tint)
| Oaddrstack _ => (nil, Tint)
- | Oundef => (nil, Tint) (* treated specially *)
| Ocast8signed => (Tint :: nil, Tint)
| Ocast8unsigned => (Tint :: nil, Tint)
| Ocast16signed => (Tint :: nil, Tint)
@@ -471,40 +529,40 @@ Variable A: Set.
Variable genv: Genv.t A.
Lemma type_of_operation_sound:
- forall op vl sp v,
- op <> Omove -> op <> Oundef ->
- eval_operation genv sp op vl = Some v ->
+ forall op vl sp v m,
+ op <> Omove ->
+ eval_operation genv sp op vl m = Some v ->
Val.has_type v (snd (type_of_operation op)).
Proof.
intros.
- destruct op; simpl in H1; FuncInv; try subst v; try exact I.
+ destruct op; simpl in H0; FuncInv; try subst v; try exact I.
congruence.
- destruct (Genv.find_symbol genv i); simplify_eq H1; intro; subst v; exact I.
- simpl. unfold offset_sp in H1. destruct sp; try discriminate.
- inversion H1. exact I.
+ destruct (Genv.find_symbol genv i); simplify_eq H0; intro; subst v; exact I.
+ simpl. unfold offset_sp in H0. destruct sp; try discriminate.
+ inversion H0. exact I.
destruct v0; exact I.
destruct v0; exact I.
destruct v0; exact I.
destruct v0; exact I.
- destruct (eq_block b b0). injection H1; intro; subst v; exact I.
+ destruct (eq_block b b0). injection H0; intro; subst v; exact I.
discriminate.
destruct (Int.eq i0 Int.zero). discriminate.
- injection H1; intro; subst v; exact I.
+ injection H0; intro; subst v; exact I.
destruct (Int.eq i0 Int.zero). discriminate.
- injection H1; intro; subst v; exact I.
+ injection H0; intro; subst v; exact I.
destruct (Int.ltu i0 (Int.repr 32)).
- injection H1; intro; subst v; exact I. discriminate.
+ injection H0; intro; subst v; exact I. discriminate.
destruct (Int.ltu i0 (Int.repr 32)).
- injection H1; intro; subst v; exact I. discriminate.
+ injection H0; intro; subst v; exact I. discriminate.
destruct (Int.ltu i (Int.repr 32)).
- injection H1; intro; subst v; exact I. discriminate.
+ injection H0; intro; subst v; exact I. discriminate.
destruct (Int.ltu i (Int.repr 32)).
- injection H1; intro; subst v; exact I. discriminate.
+ injection H0; intro; subst v; exact I. discriminate.
destruct (Int.ltu i0 (Int.repr 32)).
- injection H1; intro; subst v; exact I. discriminate.
+ injection H0; intro; subst v; exact I. discriminate.
destruct v0; exact I.
destruct (eval_condition c vl).
- destruct b; injection H1; intro; subst v; exact I.
+ destruct b; injection H0; intro; subst v; exact I.
discriminate.
Qed.
@@ -519,7 +577,7 @@ Proof.
intros until v. unfold Mem.loadv.
destruct addr; intros; try discriminate.
generalize (Mem.load_inv _ _ _ _ _ H0).
- intros [X [Y [Z W]]]. subst v. apply H.
+ intros [X Y]. subst v. apply H.
Qed.
End SOUNDNESS.
@@ -559,7 +617,6 @@ Definition eval_operation_total (sp: val) (op: operation) (vl: list val) : val :
| Ofloatconst n, nil => Vfloat n
| Oaddrsymbol s ofs, nil => find_symbol_offset s ofs
| Oaddrstack ofs, nil => Val.add sp (Vint ofs)
- | Oundef, nil => Vundef
| Ocast8signed, v1::nil => Val.cast8signed v1
| Ocast8unsigned, v1::nil => Val.cast8unsigned v1
| Ocast16signed, v1::nil => Val.cast16signed v1
@@ -625,23 +682,25 @@ Proof.
Qed.
Lemma eval_condition_weaken:
- forall c vl b,
- eval_condition c vl = Some b ->
+ forall c vl m b,
+ eval_condition c vl m = Some b ->
eval_condition_total c vl = Val.of_bool b.
Proof.
intros.
unfold eval_condition in H; destruct c; FuncInv;
try subst b; try reflexivity; simpl;
try (apply eval_compare_null_weaken; auto).
+ destruct (valid_pointer m b0 (Int.signed i) &&
+ valid_pointer m b1 (Int.signed i0)).
unfold eq_block in H. destruct (zeq b0 b1); congruence.
- unfold eq_block in H. destruct (zeq b0 b1); congruence.
+ discriminate.
symmetry. apply Val.notbool_negb_1.
symmetry. apply Val.notbool_negb_1.
Qed.
Lemma eval_operation_weaken:
- forall sp op vl v,
- eval_operation genv sp op vl = Some v ->
+ forall sp op vl m v,
+ eval_operation genv sp op vl m = Some v ->
eval_operation_total sp op vl = v.
Proof.
intros.
@@ -660,9 +719,9 @@ Proof.
destruct (Int.ltu i (Int.repr 32)); congruence.
destruct (Int.ltu i (Int.repr 32)); congruence.
destruct (Int.ltu i0 (Int.repr 32)); congruence.
- caseEq (eval_condition c vl); intros; rewrite H0 in H.
+ caseEq (eval_condition c vl m); intros; rewrite H0 in H.
replace v with (Val.of_bool b).
- apply eval_condition_weaken; auto.
+ eapply eval_condition_weaken; eauto.
destruct b; simpl; congruence.
discriminate.
Qed.
@@ -702,3 +761,95 @@ Proof.
Qed.
End EVAL_OP_TOTAL.
+
+(** Compatibility of the evaluation functions with the
+ ``is less defined'' relation over values and memory states. *)
+
+Section EVAL_LESSDEF.
+
+Variable F: Set.
+Variable genv: Genv.t F.
+Variables m1 m2: mem.
+Hypothesis MEM: Mem.lessdef m1 m2.
+
+Ltac InvLessdef :=
+ match goal with
+ | [ H: Val.lessdef (Vint _) _ |- _ ] =>
+ inv H; InvLessdef
+ | [ H: Val.lessdef (Vfloat _) _ |- _ ] =>
+ inv H; InvLessdef
+ | [ H: Val.lessdef (Vptr _ _) _ |- _ ] =>
+ inv H; InvLessdef
+ | [ H: Val.lessdef_list nil _ |- _ ] =>
+ inv H; InvLessdef
+ | [ H: Val.lessdef_list (_ :: _) _ |- _ ] =>
+ inv H; InvLessdef
+ | _ => idtac
+ end.
+
+Lemma eval_condition_lessdef:
+ forall cond vl1 vl2 b,
+ Val.lessdef_list vl1 vl2 ->
+ eval_condition cond vl1 m1 = Some b ->
+ eval_condition cond vl2 m2 = Some b.
+Proof.
+ intros. destruct cond; simpl in *; FuncInv; InvLessdef; auto.
+ generalize H0.
+ caseEq (valid_pointer m1 b0 (Int.signed i)); intro; simpl; try congruence.
+ caseEq (valid_pointer m1 b1 (Int.signed i0)); intro; simpl; try congruence.
+ destruct (eq_block b0 b1); try congruence.
+ intro. inv H2.
+ rewrite (Mem.valid_pointer_lessdef _ _ _ _ MEM H1).
+ rewrite (Mem.valid_pointer_lessdef _ _ _ _ MEM H).
+ auto.
+Qed.
+
+Ltac TrivialExists :=
+ match goal with
+ | [ |- exists v2, Some ?v1 = Some v2 /\ Val.lessdef ?v1 v2 ] =>
+ exists v1; split; [auto | constructor]
+ | _ => idtac
+ end.
+
+Lemma eval_operation_lessdef:
+ forall sp op vl1 vl2 v1,
+ Val.lessdef_list vl1 vl2 ->
+ eval_operation genv sp op vl1 m1 = Some v1 ->
+ exists v2, eval_operation genv sp op vl2 m2 = Some v2 /\ Val.lessdef v1 v2.
+Proof.
+ intros. destruct op; simpl in *; FuncInv; InvLessdef; TrivialExists.
+ exists v2; auto.
+ destruct (Genv.find_symbol genv i); inv H0. TrivialExists.
+ exists v1; auto.
+ exists (Val.cast8signed v2); split. auto. apply Val.cast8signed_lessdef; auto.
+ exists (Val.cast8unsigned v2); split. auto. apply Val.cast8unsigned_lessdef; auto.
+ exists (Val.cast16signed v2); split. auto. apply Val.cast16signed_lessdef; auto.
+ exists (Val.cast16unsigned v2); split. auto. apply Val.cast16unsigned_lessdef; auto.
+ destruct (eq_block b b0); inv H0. TrivialExists.
+ destruct (Int.eq i0 Int.zero); inv H0; TrivialExists.
+ destruct (Int.eq i0 Int.zero); inv H0; TrivialExists.
+ destruct (Int.ltu i0 (Int.repr 32)); inv H0; TrivialExists.
+ destruct (Int.ltu i0 (Int.repr 32)); inv H0; TrivialExists.
+ destruct (Int.ltu i (Int.repr 32)); inv H0; TrivialExists.
+ destruct (Int.ltu i (Int.repr 32)); inv H0; TrivialExists.
+ destruct (Int.ltu i0 (Int.repr 32)); inv H0; TrivialExists.
+ exists (Val.singleoffloat v2); split. auto. apply Val.singleoffloat_lessdef; auto.
+ caseEq (eval_condition c vl1 m1); intros. rewrite H1 in H0.
+ rewrite (eval_condition_lessdef c H H1).
+ destruct b; inv H0; TrivialExists.
+ rewrite H1 in H0. discriminate.
+Qed.
+
+Lemma eval_addressing_lessdef:
+ forall sp addr vl1 vl2 v1,
+ Val.lessdef_list vl1 vl2 ->
+ eval_addressing genv sp addr vl1 = Some v1 ->
+ exists v2, eval_addressing genv sp addr vl2 = Some v2 /\ Val.lessdef v1 v2.
+Proof.
+ intros. destruct addr; simpl in *; FuncInv; InvLessdef; TrivialExists.
+ destruct (Genv.find_symbol genv i); inv H0. TrivialExists.
+ destruct (Genv.find_symbol genv i); inv H0. TrivialExists.
+ exists v1; auto.
+Qed.
+
+End EVAL_LESSDEF.
diff --git a/backend/PPC.v b/backend/PPC.v
index ba645d0..66d96c2 100644
--- a/backend/PPC.v
+++ b/backend/PPC.v
@@ -9,6 +9,7 @@ Require Import Values.
Require Import Mem.
Require Import Events.
Require Import Globalenvs.
+Require Import Smallstep.
(** * Abstract syntax *)
@@ -97,7 +98,8 @@ Inductive instruction : Set :=
| Pbctrl: instruction (**r branch to contents of CTR and link *)
| Pbf: crbit -> label -> instruction (**r branch if false *)
| Pbl: ident -> instruction (**r branch and link *)
- | Pblr: instruction (**r branch to contents: register LR *)
+ | Pbs: ident -> instruction (**r branch to symbol *)
+ | Pblr: instruction (**r branch to contents of register LR *)
| Pbt: crbit -> label -> instruction (**r branch if true *)
| Pcmplw: ireg -> ireg -> instruction (**r unsigned integer comparison *)
| Pcmplwi: ireg -> constant -> instruction (**r same, with immediate argument *)
@@ -170,14 +172,11 @@ Inductive instruction : Set :=
| Pxor: ireg -> ireg -> ireg -> instruction (**r bitwise xor *)
| Pxori: ireg -> ireg -> constant -> instruction (**r bitwise xor with immediate *)
| Pxoris: ireg -> ireg -> constant -> instruction (**r bitwise xor with immediate high *)
- | Piundef: ireg -> instruction (**r set int reg to [Vundef] *)
- | Pfundef: freg -> instruction (**r set float reg to [Vundef] *)
| Plabel: label -> instruction. (**r define a code label *)
(** The pseudo-instructions are the following:
- [Plabel]: define a code label at the current program point
-
- [Plfi]: load a floating-point constant in a float register.
Expands to a float load [lfd] from an address in the constant data section
initialized with the floating-point constant:
@@ -190,7 +189,6 @@ lbl: .double floatcst
>>
Initialized data in the constant data section are not modeled here,
which is why we use a pseudo-instruction for this purpose.
-
- [Pfcti]: convert a float to an integer. This requires a transfer
via memory of a 32-bit integer from a float register to an int register,
which our memory model cannot express. Expands to:
@@ -200,7 +198,6 @@ lbl: .double floatcst
lwz rdst, 4(r1)
addi r1, r1, 8
>>
-
- [Pictf]: convert a signed integer to a float. This requires complicated
bit-level manipulations of IEEE floats through mixed float and integer
arithmetic over a memory word, which our memory model and axiomatization
@@ -221,7 +218,6 @@ lbl: .long 0x43300000, 0x80000000
>>
(Don't worry if you do not understand this instruction sequence: intimate
knowledge of IEEE float arithmetic is necessary.)
-
- [Piuctf]: convert an unsigned integer to a float. The expansion is close
to that [Pictf], and equally obscure.
<<
@@ -237,7 +233,6 @@ lbl: .long 0x43300000, 0x80000000
lbl: .long 0x43300000, 0x00000000
.text
>>
-
- [Pallocframe lo hi]: in the formal semantics, this pseudo-instruction
allocates a memory block with bounds [lo] and [hi], stores the value
of register [r1] (the stack pointer, by convention) at the bottom
@@ -250,7 +245,6 @@ lbl: .long 0x43300000, 0x00000000
This cannot be expressed in our memory model, which does not reflect
the fact that stack frames are adjacent and allocated/freed
following a stack discipline.
-
- [Pfreeframe]: in the formal semantics, this pseudo-instruction
reads the bottom word of the block pointed by [r1] (the stack pointer),
frees this block, and sets [r1] to the value of the bottom word.
@@ -261,27 +255,11 @@ lbl: .long 0x43300000, 0x00000000
>>
Again, our memory model cannot comprehend that this operation
frees (logically) the current stack frame.
-
- [Pallocheap]: in the formal semantics, this pseudo-instruction
allocates a heap block of size the contents of [GPR3], and leaves
a pointer to this block in [GPR3]. In the generated assembly code,
it is turned into a call to the allocation function of the run-time
system.
-
-- [Piundef] and [Pfundef]: set an integer or float register (respectively)
- to the [Vundef] value. Expand to nothing, as the PowerPC processor has
- no notion of ``undefined value''. These two pseudo-instructions are used
- to ensure that the generated PowerPC code computes exactly the same values
- as predicted by the semantics of Cminor, which explicitly set uninitialized
- local variables to the [Vundef] value. A general property of our semantics,
- not yet formally proved, is that they are monotone with respect to the
- partial ordering [Vundef <= v] over values. Consequently, if a program
- evaluates to a non-[Vundef] result [r] from an initial state that contains
- [Vundef] values, it will also evaluate to [r] if arbitrary values are put
- in the initial state instead of the [Vundef] values. This justifies
- treating [Piundef] and [Pfundef] as no-operations, leaving in the target
- register whatever value was already there instead of setting it to [Vundef].
- The formal proof of this result remains to be done, however.
*)
Definition code := list instruction.
@@ -588,6 +566,8 @@ Definition exec_instr (c: code) (i: instruction) (rs: regset) (m: mem) : outcome
end
| Pbl ident =>
OK (rs#LR <- (Val.add rs#PC Vone) #PC <- (symbol_offset ident Int.zero)) m
+ | Pbs ident =>
+ OK (rs#PC <- (symbol_offset ident Int.zero)) m
| Pblr =>
OK (rs#PC <- (rs#LR)) m
| Pbt bit lbl =>
@@ -744,10 +724,6 @@ Definition exec_instr (c: code) (i: instruction) (rs: regset) (m: mem) : outcome
OK (nextinstr (rs#rd <- (Val.xor rs#r1 (const_low cst)))) m
| Pxoris rd r1 cst =>
OK (nextinstr (rs#rd <- (Val.xor rs#r1 (const_high cst)))) m
- | Piundef rd =>
- OK (nextinstr (rs#rd <- Vundef)) m
- | Pfundef rd =>
- OK (nextinstr (rs#rd <- Vundef)) m
| Plabel lbl =>
OK (nextinstr rs) m
end.
@@ -762,7 +738,7 @@ Inductive extcall_args (rs: regset) (m: mem):
extcall_args rs m nil irl frl ofs nil
| extcall_args_int_reg: forall tyl ir1 irl frl ofs v1 vl,
v1 = rs (IR ir1) ->
- extcall_args rs m tyl irl frl (ofs + 4) vl ->
+ extcall_args rs m tyl irl frl ofs vl ->
extcall_args rs m (Tint :: tyl) (ir1 :: irl) frl ofs (v1 :: vl)
| extcall_args_int_stack: forall tyl frl ofs v1 vl,
Mem.loadv Mint32 m (Val.add (rs (IR GPR1)) (Vint (Int.repr ofs))) = Some v1 ->
@@ -770,11 +746,11 @@ Inductive extcall_args (rs: regset) (m: mem):
extcall_args rs m (Tint :: tyl) nil frl ofs (v1 :: vl)
| extcall_args_float_reg: forall tyl irl fr1 frl ofs v1 vl,
v1 = rs (FR fr1) ->
- extcall_args rs m tyl (list_drop2 irl) frl (ofs + 8) vl ->
+ extcall_args rs m tyl (list_drop2 irl) frl ofs vl ->
extcall_args rs m (Tfloat :: tyl) irl (fr1 :: frl) ofs (v1 :: vl)
| extcall_args_float_stack: forall tyl irl ofs v1 vl,
Mem.loadv Mfloat64 m (Val.add (rs (IR GPR1)) (Vint (Int.repr ofs))) = Some v1 ->
- extcall_args rs m tyl (list_drop2 irl) nil (ofs + 8) vl ->
+ extcall_args rs m tyl irl nil (ofs + 8) vl ->
extcall_args rs m (Tfloat :: tyl) irl nil ofs (v1 :: vl).
Definition extcall_arguments
@@ -783,7 +759,7 @@ Definition extcall_arguments
sg.(sig_args)
(GPR3 :: GPR4 :: GPR5 :: GPR6 :: GPR7 :: GPR8 :: GPR9 :: GPR10 :: nil)
(FPR1 :: FPR2 :: FPR3 :: FPR4 :: FPR5 :: FPR6 :: FPR7 :: FPR8 :: FPR9 :: FPR10 :: nil)
- 24 args.
+ 56 args.
Definition loc_external_result (s: signature) : preg :=
match s.(sig_res) with
@@ -794,14 +770,17 @@ Definition loc_external_result (s: signature) : preg :=
(** Execution of the instruction at [rs#PC]. *)
-Inductive exec_step: regset -> mem -> trace -> regset -> mem -> Prop :=
+Inductive state: Set :=
+ | State: regset -> mem -> state.
+
+Inductive step: state -> trace -> state -> Prop :=
| exec_step_internal:
forall b ofs c i rs m rs' m',
rs PC = Vptr b ofs ->
Genv.find_funct_ptr ge b = Some (Internal c) ->
find_instr (Int.unsigned ofs) c = Some i ->
exec_instr c i rs m = OK rs' m' ->
- exec_step rs m E0 rs' m'
+ step (State rs m) E0 (State rs' m')
| exec_step_external:
forall b ef args res rs m t rs',
rs PC = Vptr b Int.zero ->
@@ -810,33 +789,26 @@ Inductive exec_step: regset -> mem -> trace -> regset -> mem -> Prop :=
extcall_arguments rs m ef.(ef_sig) args ->
rs' = (rs#(loc_external_result ef.(ef_sig)) <- res
#PC <- (rs LR)) ->
- exec_step rs m t rs' m.
-
-(** Execution of zero, one or several instructions starting at [rs#PC]. *)
-
-Inductive exec_steps: regset -> mem -> trace -> regset -> mem -> Prop :=
- | exec_refl:
- forall rs m,
- exec_steps rs m E0 rs m
- | exec_one:
- forall rs m t rs' m',
- exec_step rs m t rs' m' ->
- exec_steps rs m t rs' m'
- | exec_trans:
- forall rs1 m1 t1 rs2 m2 t2 rs3 m3 t3,
- exec_steps rs1 m1 t1 rs2 m2 ->
- exec_steps rs2 m2 t2 rs3 m3 ->
- t3 = t1 ** t2 ->
- exec_steps rs1 m1 t3 rs3 m3.
+ step (State rs m) t (State rs' m).
End RELSEM.
-Definition exec_program (p: program) (t: trace) (r: val) : Prop :=
- let ge := Genv.globalenv p in
- let m0 := Genv.init_mem p in
- let rs0 :=
- (Pregmap.init Vundef) # PC <- (symbol_offset ge p.(prog_main) Int.zero)
- # LR <- Vzero
- # GPR1 <- (Vptr Mem.nullptr Int.zero) in
- exists rs, exists m,
- exec_steps ge rs0 m0 t rs m /\ rs#PC = Vzero /\ rs#GPR3 = r.
+Inductive initial_state (p: program): state -> Prop :=
+ | initial_state_intro:
+ let ge := Genv.globalenv p in
+ let m0 := Genv.init_mem p in
+ let rs0 :=
+ (Pregmap.init Vundef)
+ # PC <- (symbol_offset ge p.(prog_main) Int.zero)
+ # LR <- Vzero
+ # GPR1 <- (Vptr Mem.nullptr Int.zero) in
+ initial_state p (State rs0 m0).
+
+Inductive final_state: state -> int -> Prop :=
+ | final_state_intro: forall rs m r,
+ rs#PC = Vzero ->
+ rs#GPR3 = Vint r ->
+ final_state (State rs m) r.
+
+Definition exec_program (p: program) (beh: program_behavior) : Prop :=
+ program_behaves step (initial_state p) final_state (Genv.globalenv p) beh.
diff --git a/backend/PPCgen.v b/backend/PPCgen.v
index ba8ea28..d7a83b0 100644
--- a/backend/PPCgen.v
+++ b/backend/PPCgen.v
@@ -2,6 +2,7 @@
Require Import Coqlib.
Require Import Maps.
+Require Import Errors.
Require Import AST.
Require Import Integers.
Require Import Floats.
@@ -268,11 +269,6 @@ Definition transl_op
Pori (ireg_of r) (ireg_of r) (Csymbol_low_unsigned s ofs) :: k
| Oaddrstack n, nil =>
addimm (ireg_of r) GPR1 n k
- | Oundef, nil =>
- match mreg_type r with
- | Tint => Piundef (ireg_of r) :: k
- | Tfloat => Pfundef (freg_of r) :: k
- end
| Ocast8signed, a1 :: nil =>
Pextsb (ireg_of r) (ireg_of a1) :: k
| Ocast8unsigned, a1 :: nil =>
@@ -474,6 +470,17 @@ Definition transl_instr (i: Mach.instruction) (k: code) :=
Pmtctr (ireg_of r) :: Pbctrl :: k
| Mcall sig (inr symb) =>
Pbl symb :: k
+ | Mtailcall sig (inl r) =>
+ Pmtctr (ireg_of r) ::
+ Plwz GPR2 (Cint (Int.repr 12)) GPR1 ::
+ Pmtlr GPR2 ::
+ Pfreeframe ::
+ Pbctr :: k
+ | Mtailcall sig (inr symb) =>
+ Plwz GPR2 (Cint (Int.repr 12)) GPR1 ::
+ Pmtlr GPR2 ::
+ Pfreeframe ::
+ Pbs symb :: k
| Malloc =>
Pallocblock :: k
| Mlabel lbl =>
@@ -510,14 +517,17 @@ Fixpoint code_size (c: code) : Z :=
| instr :: c' => code_size c' + 1
end.
-Definition transf_function (f: Mach.function) : option PPC.code :=
+Open Local Scope string_scope.
+
+Definition transf_function (f: Mach.function) : res PPC.code :=
let c := transl_function f in
if zlt Int.max_unsigned (code_size c)
- then None
- else Some c.
+ then Errors.Error (msg "code size exceeded")
+ else Errors.OK c.
-Definition transf_fundef (f: Mach.fundef) : option PPC.fundef :=
+Definition transf_fundef (f: Mach.fundef) : res PPC.fundef :=
transf_partial_fundef transf_function f.
-Definition transf_program (p: Mach.program) : option PPC.program :=
+Definition transf_program (p: Mach.program) : res PPC.program :=
transform_partial_program transf_fundef p.
+
diff --git a/backend/PPCgenproof.v b/backend/PPCgenproof.v
index f1ee9f2..8d6d934 100644
--- a/backend/PPCgenproof.v
+++ b/backend/PPCgenproof.v
@@ -2,6 +2,7 @@
Require Import Coqlib.
Require Import Maps.
+Require Import Errors.
Require Import AST.
Require Import Integers.
Require Import Floats.
@@ -9,19 +10,22 @@ Require Import Values.
Require Import Mem.
Require Import Events.
Require Import Globalenvs.
+Require Import Smallstep.
Require Import Op.
Require Import Locations.
Require Import Mach.
+Require Import Machconcr.
Require Import Machtyping.
Require Import PPC.
Require Import PPCgen.
+Require Import PPCgenretaddr.
Require Import PPCgenproof1.
Section PRESERVATION.
Variable prog: Mach.program.
Variable tprog: PPC.program.
-Hypothesis TRANSF: transf_program prog = Some tprog.
+Hypothesis TRANSF: transf_program prog = Errors.OK tprog.
Let ge := Genv.globalenv prog.
Let tge := Genv.globalenv tprog.
@@ -35,16 +39,11 @@ Proof.
Qed.
Lemma functions_translated:
- forall f b,
+ forall b f,
Genv.find_funct_ptr ge b = Some f ->
- exists tf, Genv.find_funct_ptr tge b = Some tf /\ transf_fundef f = Some tf.
-Proof.
- intros.
- generalize (Genv.find_funct_ptr_transf_partial transf_fundef TRANSF H).
- case (transf_fundef f).
- intros f' [A B]. exists f'; split. assumption. auto.
- tauto.
-Qed.
+ exists tf, Genv.find_funct_ptr tge b = Some tf /\ transf_fundef f = Errors.OK tf.
+Proof
+ (Genv.find_funct_ptr_transf_partial transf_fundef TRANSF).
Lemma functions_transl:
forall f b,
@@ -54,8 +53,8 @@ Proof.
intros.
destruct (functions_translated _ _ H) as [tf [A B]].
rewrite A. generalize B. unfold transf_fundef, transf_partial_fundef, transf_function.
- case (zlt Int.max_unsigned (code_size (transl_function f))); intro.
- congruence. auto.
+ case (zlt Int.max_unsigned (code_size (transl_function f))); simpl; intro.
+ congruence. intro. inv B0. auto.
Qed.
Lemma functions_transl_no_overflow:
@@ -66,7 +65,7 @@ Proof.
intros.
destruct (functions_translated _ _ H) as [tf [A B]].
generalize B. unfold transf_fundef, transf_partial_fundef, transf_function.
- case (zlt Int.max_unsigned (code_size (transl_function f))); intro.
+ case (zlt Int.max_unsigned (code_size (transl_function f))); simpl; intro.
congruence. intro; omega.
Qed.
@@ -81,23 +80,17 @@ Proof.
left; congruence. right; eauto.
Qed.
-(** The ``code tail'' of an instruction list [c] is the list of instructions
- starting at PC [pos]. *)
-
-Fixpoint code_tail (pos: Z) (c: code) {struct c} : code :=
- match c with
- | nil => nil
- | i :: il => if zeq pos 0 then c else code_tail (pos - 1) il
- end.
-
Lemma find_instr_tail:
- forall c pos,
- find_instr pos c =
- match code_tail pos c with nil => None | i1 :: il => Some i1 end.
+ forall c1 i c2 pos,
+ code_tail pos c1 (i :: c2) ->
+ find_instr pos c1 = Some i.
Proof.
- induction c; simpl; intros.
- auto.
- case (zeq pos 0); auto.
+ induction c1; simpl; intros.
+ inv H.
+ destruct (zeq pos 0). subst pos.
+ inv H. auto. generalize (code_tail_pos _ _ _ H4). intro. omegaContradiction.
+ inv H. congruence. replace (pos0 + 1 - 1) with pos0 by omega.
+ eauto.
Qed.
Remark code_size_pos:
@@ -108,60 +101,39 @@ Qed.
Remark code_tail_bounds:
forall fn ofs i c,
- code_tail ofs fn = i :: c -> 0 <= ofs < code_size fn.
-Proof.
- induction fn; simpl.
- intros; discriminate.
- intros until c. case (zeq ofs 0); intros.
- generalize (code_size_pos fn). omega.
- generalize (IHfn _ _ _ H). omega.
-Qed.
-
-Remark code_tail_unfold:
- forall ofs i c,
- ofs >= 0 ->
- code_tail (ofs + 1) (i :: c) = code_tail ofs c.
-Proof.
- intros. simpl. case (zeq (ofs + 1) 0); intros.
- omegaContradiction.
- replace (ofs + 1 - 1) with ofs. auto. omega.
-Qed.
-
-Remark code_tail_zero:
- forall fn, code_tail 0 fn = fn.
+ code_tail ofs fn (i :: c) -> 0 <= ofs < code_size fn.
Proof.
- intros. destruct fn; simpl. auto. auto.
+ assert (forall ofs fn c, code_tail ofs fn c ->
+ forall i c', c = i :: c' -> 0 <= ofs < code_size fn).
+ induction 1; intros; simpl.
+ rewrite H. simpl. generalize (code_size_pos c'). omega.
+ generalize (IHcode_tail _ _ H0). omega.
+ eauto.
Qed.
Lemma code_tail_next:
forall fn ofs i c,
- code_tail ofs fn = i :: c ->
- code_tail (ofs + 1) fn = c.
+ code_tail ofs fn (i :: c) ->
+ code_tail (ofs + 1) fn c.
Proof.
- induction fn.
- simpl; intros; discriminate.
- intros until c. case (zeq ofs 0); intro.
- subst ofs. intros. rewrite code_tail_zero in H. injection H.
- intros. subst c. rewrite code_tail_unfold. apply code_tail_zero.
- omega.
- intro; generalize (code_tail_bounds _ _ _ _ H); intros [A B].
- assert (ofs = (ofs - 1) + 1). omega.
- rewrite H0 in H. rewrite code_tail_unfold in H.
- rewrite code_tail_unfold. rewrite H0. eauto.
- omega. omega.
+ assert (forall ofs fn c, code_tail ofs fn c ->
+ forall i c', c = i :: c' -> code_tail (ofs + 1) fn c').
+ induction 1; intros.
+ subst c. constructor. constructor.
+ constructor. eauto.
+ eauto.
Qed.
Lemma code_tail_next_int:
forall fn ofs i c,
code_size fn <= Int.max_unsigned ->
- code_tail (Int.unsigned ofs) fn = i :: c ->
- code_tail (Int.unsigned (Int.add ofs Int.one)) fn = c.
+ code_tail (Int.unsigned ofs) fn (i :: c) ->
+ code_tail (Int.unsigned (Int.add ofs Int.one)) fn c.
Proof.
- intros. rewrite Int.add_unsigned. unfold Int.one.
- repeat rewrite Int.unsigned_repr. apply code_tail_next with i; auto.
- compute; intuition congruence.
+ intros. rewrite Int.add_unsigned.
+ change (Int.unsigned Int.one) with 1.
+ rewrite Int.unsigned_repr. apply code_tail_next with i; auto.
generalize (code_tail_bounds _ _ _ _ H0). omega.
- compute; intuition congruence.
Qed.
(** [transl_code_at_pc pc fn c] holds if the code pointer [pc] points
@@ -169,12 +141,12 @@ Qed.
and [c] is the tail of the generated code at the position corresponding
to the code pointer [pc]. *)
-Inductive transl_code_at_pc: val -> Mach.function -> Mach.code -> Prop :=
+Inductive transl_code_at_pc: val -> block -> Mach.function -> Mach.code -> Prop :=
transl_code_at_pc_intro:
forall b ofs f c,
Genv.find_funct_ptr ge b = Some (Internal f) ->
- code_tail (Int.unsigned ofs) (transl_function f) = transl_code c ->
- transl_code_at_pc (Vptr b ofs) f c.
+ code_tail (Int.unsigned ofs) (transl_function f) (transl_code c) ->
+ transl_code_at_pc (Vptr b ofs) b f c.
(** The following lemmas show that straight-line executions
(predicate [exec_straight]) correspond to correct PPC executions
@@ -187,14 +159,16 @@ Lemma exec_straight_steps_1:
forall b ofs,
rs#PC = Vptr b ofs ->
Genv.find_funct_ptr tge b = Some (Internal fn) ->
- code_tail (Int.unsigned ofs) fn = c ->
- exec_steps tge rs m E0 rs' m'.
+ code_tail (Int.unsigned ofs) fn c ->
+ plus step tge (State rs m) E0 (State rs' m').
Proof.
- induction 1.
- intros. apply exec_refl.
- intros. apply exec_trans with E0 rs2 m2 E0.
- apply exec_one; econstructor; eauto.
- rewrite find_instr_tail. rewrite H5. auto.
+ induction 1; intros.
+ apply plus_one.
+ econstructor; eauto.
+ eapply find_instr_tail. eauto.
+ eapply plus_left'.
+ econstructor; eauto.
+ eapply find_instr_tail. eauto.
apply IHexec_straight with b (Int.add ofs Int.one).
auto. rewrite H0. rewrite H3. reflexivity.
auto.
@@ -209,35 +183,79 @@ Lemma exec_straight_steps_2:
forall b ofs,
rs#PC = Vptr b ofs ->
Genv.find_funct_ptr tge b = Some (Internal fn) ->
- code_tail (Int.unsigned ofs) fn = c ->
+ code_tail (Int.unsigned ofs) fn c ->
exists ofs',
rs'#PC = Vptr b ofs'
- /\ code_tail (Int.unsigned ofs') fn = c'.
+ /\ code_tail (Int.unsigned ofs') fn c'.
Proof.
induction 1; intros.
- exists ofs. split. auto. auto.
+ exists (Int.add ofs Int.one). split.
+ rewrite H0. rewrite H2. auto.
+ apply code_tail_next_int with i1; auto.
apply IHexec_straight with (Int.add ofs Int.one).
auto. rewrite H0. rewrite H3. reflexivity. auto.
apply code_tail_next_int with i; auto.
Qed.
-Lemma exec_straight_steps:
- forall f c c' rs m rs' m',
- transl_code_at_pc (rs PC) f c ->
+Lemma exec_straight_exec:
+ forall fb f c c' rs m rs' m',
+ transl_code_at_pc (rs PC) fb f c ->
+ exec_straight tge (transl_function f)
+ (transl_code c) rs m c' rs' m' ->
+ plus step tge (State rs m) E0 (State rs' m').
+Proof.
+ intros. inversion H. subst.
+ eapply exec_straight_steps_1; eauto.
+ eapply functions_transl_no_overflow; eauto.
+ eapply functions_transl; eauto.
+Qed.
+
+Lemma exec_straight_at:
+ forall fb f c c' rs m rs' m',
+ transl_code_at_pc (rs PC) fb f c ->
exec_straight tge (transl_function f)
(transl_code c) rs m (transl_code c') rs' m' ->
- exec_steps tge rs m E0 rs' m' /\ transl_code_at_pc (rs' PC) f c'.
+ transl_code_at_pc (rs' PC) fb f c'.
Proof.
- intros. inversion H.
+ intros. inversion H. subst.
generalize (functions_transl_no_overflow _ _ H2). intro.
generalize (functions_transl _ _ H2). intro.
- split. eapply exec_straight_steps_1; eauto.
generalize (exec_straight_steps_2 _ _ _ _ _ _ _
- H0 H6 _ _ (sym_equal H1) H7 H3).
+ H0 H4 _ _ (sym_equal H1) H5 H3).
intros [ofs' [PC' CT']].
rewrite PC'. constructor; auto.
Qed.
+(** Correctness of the return addresses predicted by
+ [PPCgen.return_address_offset]. *)
+
+Remark code_tail_no_bigger:
+ forall pos c1 c2, code_tail pos c1 c2 -> (length c2 <= length c1)%nat.
+Proof.
+ induction 1; simpl; omega.
+Qed.
+
+Remark code_tail_unique:
+ forall fn c pos pos',
+ code_tail pos fn c -> code_tail pos' fn c -> pos = pos'.
+Proof.
+ induction fn; intros until pos'; intros ITA CT; inv ITA; inv CT; auto.
+ generalize (code_tail_no_bigger _ _ _ H3); simpl; intro; omega.
+ generalize (code_tail_no_bigger _ _ _ H3); simpl; intro; omega.
+ f_equal. eauto.
+Qed.
+
+Lemma return_address_offset_correct:
+ forall b ofs fb f c ofs',
+ transl_code_at_pc (Vptr b ofs) fb f c ->
+ return_address_offset f c ofs' ->
+ ofs' = ofs.
+Proof.
+ intros. inv H0. inv H.
+ generalize (code_tail_unique _ _ _ _ H1 H7). intro. rewrite H.
+ apply Int.repr_unsigned.
+Qed.
+
(** The [find_label] function returns the code tail starting at the
given label. A connection with [code_tail] is then established. *)
@@ -253,7 +271,7 @@ Lemma label_pos_code_tail:
find_label lbl c = Some c' ->
exists pos',
label_pos lbl pos c = Some pos'
- /\ code_tail (pos' - pos) c = c'
+ /\ code_tail (pos' - pos) c c'
/\ pos < pos' <= pos + code_size c.
Proof.
induction c.
@@ -262,13 +280,13 @@ Proof.
case (is_label lbl a).
intro EQ; injection EQ; intro; subst c'.
exists (pos + 1). split. auto. split.
- rewrite zeq_false. replace (pos + 1 - pos - 1) with 0.
- apply code_tail_zero. omega. omega.
+ replace (pos + 1 - pos) with (0 + 1) by omega. constructor. constructor.
generalize (code_size_pos c). omega.
intros. generalize (IHc (pos + 1) c' H). intros [pos' [A [B C]]].
exists pos'. split. auto. split.
- rewrite zeq_false. replace (pos' - pos - 1) with (pos' - (pos + 1)).
- auto. omega. omega. omega.
+ replace (pos' - pos) with ((pos' - (pos + 1)) + 1) by omega.
+ constructor. auto.
+ omega.
Qed.
(** The following lemmas show that the translation from Mach to PPC
@@ -409,7 +427,6 @@ Proof.
destruct op; destruct args; try (destruct args); try (destruct args); try (destruct args);
try reflexivity; autorewrite with labels; try reflexivity.
case (mreg_type m); reflexivity.
- case (mreg_type r); reflexivity.
case (Int.eq (high_s i) Int.zero); autorewrite with labels; reflexivity.
case (Int.eq (high_s i) Int.zero); autorewrite with labels; reflexivity.
case (snd (crbit_for_cond c)); reflexivity.
@@ -453,6 +470,7 @@ Proof.
destruct m; rewrite transl_load_store_label; intros; reflexivity.
destruct m; rewrite transl_load_store_label; intros; reflexivity.
destruct s0; reflexivity.
+ destruct s0; reflexivity.
rewrite peq_false. auto. congruence.
case (snd (crbit_for_cond c)); reflexivity.
Qed.
@@ -488,7 +506,7 @@ Lemma find_label_goto_label:
Mach.find_label lbl f.(fn_code) = Some c' ->
exists rs',
goto_label (transl_function f) lbl rs m = OK rs' m
- /\ transl_code_at_pc (rs' PC) f c'
+ /\ transl_code_at_pc (rs' PC) b f c'
/\ forall r, r <> PC -> rs'#r = rs#r.
Proof.
intros.
@@ -499,13 +517,13 @@ Proof.
intros [pos' [A [B C]]].
exists (rs#PC <- (Vptr b (Int.repr pos'))).
split. unfold goto_label. rewrite A. rewrite H0. auto.
- split. rewrite Pregmap.gss. constructor. auto.
+ split. rewrite Pregmap.gss. constructor; auto.
rewrite Int.unsigned_repr. replace (pos' - 0) with pos' in B.
auto. omega.
generalize (functions_transl_no_overflow _ _ H).
omega.
intros. apply Pregmap.gso; auto.
-Qed.
+Qed.
(** * Memory properties *)
@@ -513,22 +531,39 @@ Qed.
We show that it can be synthesized as a ``load 8-bit unsigned integer''
followed by a sign extension. *)
+Remark valid_access_equiv:
+ forall chunk1 chunk2 m b ofs,
+ size_chunk chunk1 = size_chunk chunk2 ->
+ valid_access m chunk1 b ofs ->
+ valid_access m chunk2 b ofs.
+Proof.
+ intros. inv H0. rewrite H in H3. constructor; auto.
+Qed.
+
+Remark in_bounds_equiv:
+ forall chunk1 chunk2 m b ofs (A: Set) (a1 a2: A),
+ size_chunk chunk1 = size_chunk chunk2 ->
+ (if in_bounds m chunk1 b ofs then a1 else a2) =
+ (if in_bounds m chunk2 b ofs then a1 else a2).
+Proof.
+ intros. destruct (in_bounds m chunk1 b ofs).
+ rewrite in_bounds_true. auto. eapply valid_access_equiv; eauto.
+ destruct (in_bounds m chunk2 b ofs); auto.
+ elim n. eapply valid_access_equiv with (chunk1 := chunk2); eauto.
+Qed.
+
Lemma loadv_8_signed_unsigned:
forall m a,
Mem.loadv Mint8signed m a =
option_map Val.cast8signed (Mem.loadv Mint8unsigned m a).
Proof.
intros. unfold Mem.loadv. destruct a; try reflexivity.
- unfold load. case (zlt b (nextblock m)); intro.
- change (in_bounds Mint8unsigned (Int.signed i) (blocks m b))
- with (in_bounds Mint8signed (Int.signed i) (blocks m b)).
- case (in_bounds Mint8signed (Int.signed i) (blocks m b)).
- change (mem_chunk Mint8unsigned) with (mem_chunk Mint8signed).
- set (v := (load_contents (mem_chunk Mint8signed)
- (contents (blocks m b)) (Int.signed i))).
- unfold Val.load_result. destruct v; try reflexivity.
+ unfold load. rewrite (in_bounds_equiv Mint8signed Mint8unsigned).
+ destruct (in_bounds m Mint8unsigned b (Int.signed i)); auto.
+ simpl.
+ destruct (getN 0 (Int.signed i) (contents (blocks m b))); auto.
simpl. rewrite Int.cast8_signed_unsigned. auto.
- reflexivity. reflexivity.
+ auto.
Qed.
(** Similarly, we show that signed 8- and 16-bit stores can be performed
@@ -538,155 +573,201 @@ Lemma storev_8_signed_unsigned:
forall m a v,
Mem.storev Mint8signed m a v = Mem.storev Mint8unsigned m a v.
Proof.
- intros. reflexivity.
+ intros. unfold storev. destruct a; auto.
+ unfold store. rewrite (in_bounds_equiv Mint8signed Mint8unsigned).
+ auto. auto.
Qed.
Lemma storev_16_signed_unsigned:
forall m a v,
Mem.storev Mint16signed m a v = Mem.storev Mint16unsigned m a v.
Proof.
- intros. reflexivity.
+ intros. unfold storev. destruct a; auto.
+ unfold store. rewrite (in_bounds_equiv Mint16signed Mint16unsigned).
+ auto. auto.
Qed.
(** * Proof of semantic preservation *)
-(** The invariants for the inductive proof of simulation are as follows.
- The simulation diagrams are of the form:
+(** Semantic preservation is proved using simulation diagrams
+ of the following form.
<<
- c1, ms1, m1 --------------------- rs1, m1
- | |
- | |
- v v
- c2, ms2, m2 --------------------- rs2, m2
+ st1 --------------- st2
+ | |
+ t| *|t
+ | |
+ v v
+ st1'--------------- st2'
>>
- Left: execution of one Mach instruction. Right: execution of zero, one
- or several instructions. Precondition (top): agreement between
- the Mach register set [ms1] and the PPC register set [rs1]; moreover,
- [rs1 PC] points to the translation of code [c1]. Postcondition (bottom):
- similar.
+ The invariant is the [match_states] predicate below, which includes:
+- The PPC code pointed by the PC register is the translation of
+ the current Mach code sequence.
+- Mach register values and PPC register values agree.
*)
-Definition exec_instr_prop
- (f: Mach.function) (sp: val)
- (c1: Mach.code) (ms1: Mach.regset) (m1: mem) (t: trace)
- (c2: Mach.code) (ms2: Mach.regset) (m2: mem) :=
- forall rs1
- (WTF: wt_function f)
- (INCL: incl c1 f.(fn_code))
- (AT: transl_code_at_pc (rs1 PC) f c1)
- (AG: agree ms1 sp rs1),
- exists rs2,
- agree ms2 sp rs2
- /\ exec_steps tge rs1 m1 t rs2 m2
- /\ transl_code_at_pc (rs2 PC) f c2.
-
-Definition exec_function_body_prop
- (f: Mach.function) (parent: val) (ra: val)
- (ms1: Mach.regset) (m1: mem) (t: trace)
- (ms2: Mach.regset) (m2: mem) :=
- forall rs1
- (WTRA: Val.has_type ra Tint)
- (RALR: rs1 LR = ra)
- (WTF: wt_function f)
- (AT: Genv.find_funct ge (rs1 PC) = Some (Internal f))
- (AG: agree ms1 parent rs1),
- exists rs2,
- agree ms2 parent rs2
- /\ exec_steps tge rs1 m1 t rs2 m2
- /\ rs2 PC = rs1 LR.
-
-Definition exec_function_prop
- (f: Mach.fundef) (parent: val)
- (ms1: Mach.regset) (m1: mem) (t: trace)
- (ms2: Mach.regset) (m2: mem) :=
- forall rs1
- (WTF: wt_fundef f)
- (AT: Genv.find_funct ge (rs1 PC) = Some f)
- (AG: agree ms1 parent rs1)
- (WTRA: Val.has_type (rs1 LR) Tint),
- exists rs2,
- agree ms2 parent rs2
- /\ exec_steps tge rs1 m1 t rs2 m2
- /\ rs2 PC = rs1 LR.
-
-(** We show each case of the inductive proof of simulation as a separate
- lemma. *)
+Inductive match_stack: list Machconcr.stackframe -> Prop :=
+ | match_stack_nil:
+ match_stack nil
+ | match_stack_cons: forall fb sp ra c s f,
+ Genv.find_funct_ptr ge fb = Some (Internal f) ->
+ wt_function f ->
+ incl c f.(fn_code) ->
+ transl_code_at_pc ra fb f c ->
+ match_stack s ->
+ match_stack (Stackframe fb sp ra c :: s).
+
+Inductive match_states: Machconcr.state -> PPC.state -> Prop :=
+ | match_states_intro:
+ forall s fb sp c ms m rs f
+ (STACKS: match_stack s)
+ (FIND: Genv.find_funct_ptr ge fb = Some (Internal f))
+ (WTF: wt_function f)
+ (INCL: incl c f.(fn_code))
+ (AT: transl_code_at_pc (rs PC) fb f c)
+ (AG: agree ms sp rs),
+ match_states (Machconcr.State s fb sp c ms m)
+ (PPC.State rs m)
+ | match_states_call:
+ forall s fb ms m rs
+ (STACKS: match_stack s)
+ (AG: agree ms (parent_sp s) rs)
+ (ATPC: rs PC = Vptr fb Int.zero)
+ (ATLR: rs LR = parent_ra s),
+ match_states (Machconcr.Callstate s fb ms m)
+ (PPC.State rs m)
+ | match_states_return:
+ forall s ms m rs
+ (STACKS: match_stack s)
+ (AG: agree ms (parent_sp s) rs)
+ (ATPC: rs PC = parent_ra s),
+ match_states (Machconcr.Returnstate s ms m)
+ (PPC.State rs m).
+
+Lemma exec_straight_steps:
+ forall s fb sp m1 f c1 rs1 c2 m2 ms2,
+ match_stack s ->
+ Genv.find_funct_ptr ge fb = Some (Internal f) ->
+ wt_function f ->
+ incl c2 f.(fn_code) ->
+ transl_code_at_pc (rs1 PC) fb f c1 ->
+ (exists rs2,
+ exec_straight tge (transl_function f) (transl_code c1) rs1 m1 (transl_code c2) rs2 m2
+ /\ agree ms2 sp rs2) ->
+ exists st',
+ plus step tge (State rs1 m1) E0 st' /\
+ match_states (Machconcr.State s fb sp c2 ms2 m2) st'.
+Proof.
+ intros. destruct H4 as [rs2 [A B]].
+ exists (State rs2 m2); split.
+ eapply exec_straight_exec; eauto.
+ econstructor; eauto. eapply exec_straight_at; eauto.
+Qed.
+
+(** We need to show that, in the simulation diagram, we cannot
+ take infinitely many Mach transitions that correspond to zero
+ transitions on the PPC side. Actually, all Mach transitions
+ correspond to at least one PPC transition, except the
+ transition from [Machconcr.Returnstate] to [Machconcr.State].
+ So, the following integer measure will suffice to rule out
+ the unwanted behaviour. *)
+
+Definition measure (s: Machconcr.state) : nat :=
+ match s with
+ | Machconcr.State _ _ _ _ _ _ => 0%nat
+ | Machconcr.Callstate _ _ _ _ => 0%nat
+ | Machconcr.Returnstate _ _ _ => 1%nat
+ end.
+
+(** We show the simulation diagram by case analysis on the Mach transition
+ on the left. Since the proof is large, we break it into one lemma
+ per transition. *)
+
+Definition exec_instr_prop (s1: Machconcr.state) (t: trace) (s2: Machconcr.state) : Prop :=
+ forall s1' (MS: match_states s1 s1'),
+ (exists s2', plus step tge s1' t s2' /\ match_states s2 s2')
+ \/ (measure s2 < measure s1 /\ t = E0 /\ match_states s2 s1')%nat.
+
Lemma exec_Mlabel_prop:
- forall (f : function) (sp : val) (lbl : Mach.label)
- (c : list Mach.instruction) (rs : Mach.regset) (m : mem),
- exec_instr_prop f sp (Mlabel lbl :: c) rs m E0 c rs m.
+ forall (s : list stackframe) (fb : block) (sp : val)
+ (lbl : Mach.label) (c : list Mach.instruction) (ms : Mach.regset)
+ (m : mem),
+ exec_instr_prop (Machconcr.State s fb sp (Mlabel lbl :: c) ms m) E0
+ (Machconcr.State s fb sp c ms m).
Proof.
- intros; red; intros.
- assert (exec_straight tge (transl_function f)
- (transl_code (Mlabel lbl :: c)) rs1 m
- (transl_code c) (nextinstr rs1) m).
+ intros; red; intros; inv MS.
+ left; eapply exec_straight_steps; eauto with coqlib.
+ exists (nextinstr rs); split.
simpl. apply exec_straight_one. reflexivity. reflexivity.
- exists (nextinstr rs1). split. apply agree_nextinstr; auto.
- eapply exec_straight_steps; eauto.
+ apply agree_nextinstr; auto.
Qed.
Lemma exec_Mgetstack_prop:
- forall (f : function) (sp : val) (ofs : int) (ty : typ) (dst : mreg)
- (c : list Mach.instruction) (ms : Mach.regset) (m : mem) (v : val),
- load_stack m sp ty ofs = Some v ->
- exec_instr_prop f sp (Mgetstack ofs ty dst :: c) ms m E0 c (Regmap.set dst v ms) m.
+ forall (s : list stackframe) (fb : block) (sp : val) (ofs : int)
+ (ty : typ) (dst : mreg) (c : list Mach.instruction)
+ (ms : Mach.regset) (m : mem) (v : val),
+ load_stack m sp ty ofs = Some v ->
+ exec_instr_prop (Machconcr.State s fb sp (Mgetstack ofs ty dst :: c) ms m) E0
+ (Machconcr.State s fb sp c (Regmap.set dst v ms) m).
Proof.
- intros; red; intros.
+ intros; red; intros; inv MS.
unfold load_stack in H.
generalize (wt_function_instrs _ WTF _ (INCL _ (in_eq _ _))).
intro WTI. inversion WTI.
rewrite (sp_val _ _ _ AG) in H.
assert (NOTE: GPR1 <> GPR0). congruence.
generalize (loadind_correct tge (transl_function f) GPR1 ofs ty
- dst (transl_code c) rs1 m v H H1 NOTE).
+ dst (transl_code c) rs m v H H1 NOTE).
intros [rs2 [EX [RES OTH]]].
- exists rs2. split.
- apply agree_exten_2 with (rs1#(preg_of dst) <- v).
+ left; eapply exec_straight_steps; eauto with coqlib.
+ simpl. exists rs2; split. auto.
+ apply agree_exten_2 with (rs#(preg_of dst) <- v).
auto with ppcgen.
intros. case (preg_eq r0 (preg_of dst)); intro.
subst r0. rewrite Pregmap.gss. auto.
- rewrite Pregmap.gso; auto.
- eapply exec_straight_steps; eauto.
+ rewrite Pregmap.gso; auto.
Qed.
Lemma exec_Msetstack_prop:
- forall (f : function) (sp : val) (src : mreg) (ofs : int) (ty : typ)
- (c : list Mach.instruction) (ms : mreg -> val) (m m' : mem),
- store_stack m sp ty ofs (ms src) = Some m' ->
- exec_instr_prop f sp (Msetstack src ofs ty :: c) ms m E0 c ms m'.
+ forall (s : list stackframe) (fb : block) (sp : val) (src : mreg)
+ (ofs : int) (ty : typ) (c : list Mach.instruction)
+ (ms : mreg -> val) (m m' : mem),
+ store_stack m sp ty ofs (ms src) = Some m' ->
+ exec_instr_prop (Machconcr.State s fb sp (Msetstack src ofs ty :: c) ms m) E0
+ (Machconcr.State s fb sp c ms m').
Proof.
- intros; red; intros.
+ intros; red; intros; inv MS.
unfold store_stack in H.
generalize (wt_function_instrs _ WTF _ (INCL _ (in_eq _ _))).
intro WTI. inversion WTI.
rewrite (sp_val _ _ _ AG) in H.
- rewrite (preg_val ms sp rs1) in H; auto.
+ rewrite (preg_val ms sp rs) in H; auto.
assert (NOTE: GPR1 <> GPR0). congruence.
generalize (storeind_correct tge (transl_function f) GPR1 ofs ty
- src (transl_code c) rs1 m m' H H2 NOTE).
+ src (transl_code c) rs m m' H H1 NOTE).
intros [rs2 [EX OTH]].
- exists rs2. split.
- apply agree_exten_2 with rs1; auto.
- eapply exec_straight_steps; eauto.
+ left; eapply exec_straight_steps; eauto with coqlib.
+ exists rs2; split; auto.
+ apply agree_exten_2 with rs; auto.
Qed.
Lemma exec_Mgetparam_prop:
- forall (f : function) (sp parent : val) (ofs : int) (ty : typ)
- (dst : mreg) (c : list Mach.instruction) (ms : Mach.regset)
- (m : mem) (v : val),
- load_stack m sp Tint (Int.repr 0) = Some parent ->
- load_stack m parent ty ofs = Some v ->
- exec_instr_prop f sp (Mgetparam ofs ty dst :: c) ms m E0 c (Regmap.set dst v ms) m.
+ forall (s : list stackframe) (fb : block) (sp parent : val)
+ (ofs : int) (ty : typ) (dst : mreg) (c : list Mach.instruction)
+ (ms : Mach.regset) (m : mem) (v : val),
+ load_stack m sp Tint (Int.repr 0) = Some parent ->
+ load_stack m parent ty ofs = Some v ->
+ exec_instr_prop (Machconcr.State s fb sp (Mgetparam ofs ty dst :: c) ms m) E0
+ (Machconcr.State s fb sp c (Regmap.set dst v ms) m).
Proof.
- intros; red; intros.
- set (rs2 := nextinstr (rs1#GPR2 <- parent)).
+ intros; red; intros; inv MS.
+ set (rs2 := nextinstr (rs#GPR2 <- parent)).
assert (EX1: exec_straight tge (transl_function f)
- (transl_code (Mgetparam ofs ty dst :: c)) rs1 m
+ (transl_code (Mgetparam ofs ty dst :: c)) rs m
(loadind GPR2 ofs ty dst (transl_code c)) rs2 m).
simpl. apply exec_straight_one.
simpl. unfold load1. rewrite gpr_or_zero_not_zero; auto with ppcgen.
- unfold const_low. rewrite <- (sp_val ms sp rs1); auto.
+ unfold const_low. rewrite <- (sp_val ms sp rs); auto.
unfold load_stack in H. simpl chunk_of_type in H.
rewrite H. reflexivity. reflexivity.
generalize (wt_function_instrs _ WTF _ (INCL _ (in_eq _ _))).
@@ -696,64 +777,48 @@ Proof.
generalize (loadind_correct tge (transl_function f) GPR2 ofs ty
dst (transl_code c) rs2 m v H0 H2 NOTE).
intros [rs3 [EX2 [RES OTH]]].
- exists rs3. split.
+ left; eapply exec_straight_steps; eauto with coqlib.
+ exists rs3; split; simpl.
+ eapply exec_straight_trans; eauto.
apply agree_exten_2 with (rs2#(preg_of dst) <- v).
unfold rs2; auto with ppcgen.
intros. case (preg_eq r0 (preg_of dst)); intro.
subst r0. rewrite Pregmap.gss. auto.
rewrite Pregmap.gso; auto.
- eapply exec_straight_steps; eauto.
- eapply exec_straight_trans; eauto.
-Qed.
-
-Lemma exec_straight_exec_prop:
- forall f sp c1 rs1 m1 c2 m2 ms',
- transl_code_at_pc (rs1 PC) f c1 ->
- (exists rs2,
- exec_straight tge (transl_function f)
- (transl_code c1) rs1 m1
- (transl_code c2) rs2 m2
- /\ agree ms' sp rs2) ->
- (exists rs2,
- agree ms' sp rs2
- /\ exec_steps tge rs1 m1 E0 rs2 m2
- /\ transl_code_at_pc (rs2 PC) f c2).
-Proof.
- intros until ms'. intros TRANS1 [rs2 [EX AG]].
- exists rs2. split. assumption.
- eapply exec_straight_steps; eauto.
Qed.
Lemma exec_Mop_prop:
- forall (f : function) (sp : val) (op : operation) (args : list mreg)
- (res : mreg) (c : list Mach.instruction) (ms: Mach.regset)
- (m : mem) (v: val),
- eval_operation ge sp op ms ## args = Some v ->
- exec_instr_prop f sp (Mop op args res :: c) ms m E0 c (Regmap.set res v ms) m.
+ forall (s : list stackframe) (fb : block) (sp : val) (op : operation)
+ (args : list mreg) (res : mreg) (c : list Mach.instruction)
+ (ms : mreg -> val) (m : mem) (v : val),
+ eval_operation ge sp op ms ## args m = Some v ->
+ exec_instr_prop (Machconcr.State s fb sp (Mop op args res :: c) ms m) E0
+ (Machconcr.State s fb sp c (Regmap.set res v ms) m).
Proof.
- intros; red; intros.
+ intros; red; intros; inv MS.
generalize (wt_function_instrs _ WTF _ (INCL _ (in_eq _ _))).
- intro WTI.
- eapply exec_straight_exec_prop; eauto.
+ intro WTI.
+ left; eapply exec_straight_steps; eauto with coqlib.
simpl. eapply transl_op_correct; auto.
rewrite <- H. apply eval_operation_preserved. exact symbols_preserved.
Qed.
Lemma exec_Mload_prop:
- forall (f : function) (sp : val) (chunk : memory_chunk)
- (addr : addressing) (args : list mreg) (dst : mreg)
- (c : list Mach.instruction) (ms: Mach.regset) (m : mem)
- (a v : val),
- eval_addressing ge sp addr ms ## args = Some a ->
- loadv chunk m a = Some v ->
- exec_instr_prop f sp (Mload chunk addr args dst :: c) ms m E0 c (Regmap.set dst v ms) m.
+ forall (s : list stackframe) (fb : block) (sp : val)
+ (chunk : memory_chunk) (addr : addressing) (args : list mreg)
+ (dst : mreg) (c : list Mach.instruction) (ms : mreg -> val)
+ (m : mem) (a v : val),
+ eval_addressing ge sp addr ms ## args = Some a ->
+ loadv chunk m a = Some v ->
+ exec_instr_prop (Machconcr.State s fb sp (Mload chunk addr args dst :: c) ms m)
+ E0 (Machconcr.State s fb sp c (Regmap.set dst v ms) m).
Proof.
- intros; red; intros.
+ intros; red; intros; inv MS.
generalize (wt_function_instrs _ WTF _ (INCL _ (in_eq _ _))).
intro WTI; inversion WTI.
assert (eval_addressing tge sp addr ms##args = Some a).
rewrite <- H. apply eval_addressing_preserved. exact symbols_preserved.
- eapply exec_straight_exec_prop; eauto.
+ left; eapply exec_straight_steps; eauto with coqlib;
destruct chunk; simpl; simpl in H6;
(* all cases but Mint8signed *)
try (eapply transl_load_correct; eauto;
@@ -776,7 +841,7 @@ Proof.
(Plbz (ireg_of dst)) (Plbzx (ireg_of dst))
Mint8unsigned addr args
(Pextsb (ireg_of dst) (ireg_of dst) :: transl_code c)
- ms sp rs1 m dst a v'
+ ms sp rs m dst a v'
X1 X2 AG H3 H7 LOAD').
intros [rs2 [EX1 AG1]].
exists (nextinstr (rs2#(ireg_of dst) <- v)).
@@ -788,190 +853,298 @@ Proof.
Qed.
Lemma exec_Mstore_prop:
- forall (f : function) (sp : val) (chunk : memory_chunk)
- (addr : addressing) (args : list mreg) (src : mreg)
- (c : list Mach.instruction) (ms: Mach.regset) (m m' : mem)
- (a : val),
- eval_addressing ge sp addr ms ## args = Some a ->
- storev chunk m a (ms src) = Some m' ->
- exec_instr_prop f sp (Mstore chunk addr args src :: c) ms m E0 c ms m'.
+ forall (s : list stackframe) (fb : block) (sp : val)
+ (chunk : memory_chunk) (addr : addressing) (args : list mreg)
+ (src : mreg) (c : list Mach.instruction) (ms : mreg -> val)
+ (m m' : mem) (a : val),
+ eval_addressing ge sp addr ms ## args = Some a ->
+ storev chunk m a (ms src) = Some m' ->
+ exec_instr_prop (Machconcr.State s fb sp (Mstore chunk addr args src :: c) ms m) E0
+ (Machconcr.State s fb sp c ms m').
Proof.
- intros; red; intros.
+ intros; red; intros; inv MS.
generalize (wt_function_instrs _ WTF _ (INCL _ (in_eq _ _))).
intro WTI; inversion WTI.
rewrite <- (eval_addressing_preserved symbols_preserved) in H.
- eapply exec_straight_exec_prop; eauto.
+ left; eapply exec_straight_steps; eauto with coqlib.
destruct chunk; simpl; simpl in H6;
- try (rewrite storev_8_signed_unsigned in H);
- try (rewrite storev_16_signed_unsigned in H);
+ try (rewrite storev_8_signed_unsigned in H0);
+ try (rewrite storev_16_signed_unsigned in H0);
simpl; eapply transl_store_correct; eauto;
intros; unfold preg_of; rewrite H6; reflexivity.
Qed.
-Hypothesis wt_prog: wt_program prog.
-
Lemma exec_Mcall_prop:
- forall (f : function) (sp : val) (sig : signature)
- (mos : mreg + ident) (c : list Mach.instruction) (ms : Mach.regset)
- (m : mem) (f' : Mach.fundef) (t: trace) (ms' : Mach.regset) (m' : mem),
- find_function ge mos ms = Some f' ->
- exec_function ge f' sp ms m t ms' m' ->
- exec_function_prop f' sp ms m t ms' m' ->
- exec_instr_prop f sp (Mcall sig mos :: c) ms m t c ms' m'.
+ forall (s : list stackframe) (fb : block) (sp : val)
+ (sig : signature) (ros : mreg + ident) (c : Mach.code)
+ (ms : Mach.regset) (m : mem) (f : function) (f' : block)
+ (ra : int),
+ find_function_ptr ge ros ms = Some f' ->
+ Genv.find_funct_ptr ge fb = Some (Internal f) ->
+ return_address_offset f c ra ->
+ exec_instr_prop (Machconcr.State s fb sp (Mcall sig ros :: c) ms m) E0
+ (Callstate (Stackframe fb sp (Vptr fb ra) c :: s) f' ms m).
Proof.
- intros; red; intros.
+ intros; red; intros; inv MS.
+ assert (f0 = f) by congruence. subst f0.
generalize (wt_function_instrs _ WTF _ (INCL _ (in_eq _ _))).
intro WTI. inversion WTI.
- inversion AT.
- assert (WTF': wt_fundef f').
- destruct mos; simpl in H.
- apply (Genv.find_funct_prop wt_fundef wt_prog H).
- destruct (Genv.find_symbol ge i); try discriminate.
- apply (Genv.find_funct_ptr_prop wt_fundef wt_prog H).
+ inv AT.
assert (NOOV: code_size (transl_function f) <= Int.max_unsigned).
eapply functions_transl_no_overflow; eauto.
- destruct mos; simpl in H; simpl transl_code in H7.
+ destruct ros; simpl in H; simpl transl_code in H7.
(* Indirect call *)
generalize (code_tail_next_int _ _ _ _ NOOV H7). intro CT1.
generalize (code_tail_next_int _ _ _ _ NOOV CT1). intro CT2.
- set (rs2 := nextinstr (rs1#CTR <- (ms m0))).
+ set (rs2 := nextinstr (rs#CTR <- (ms m0))).
set (rs3 := rs2 #LR <- (Val.add rs2#PC Vone) #PC <- (ms m0)).
- assert (TFIND: Genv.find_funct ge (rs3#PC) = Some f').
- unfold rs3. rewrite Pregmap.gss. auto.
+ assert (ATPC: rs3 PC = Vptr f' Int.zero).
+ change (rs3 PC) with (ms m0).
+ destruct (ms m0); try discriminate.
+ generalize H; predSpec Int.eq Int.eq_spec i Int.zero; intros; congruence.
+ exploit return_address_offset_correct; eauto. constructor; eauto.
+ intro RA_EQ.
+ assert (ATLR: rs3 LR = Vptr fb ra).
+ rewrite RA_EQ.
+ change (rs3 LR) with (Val.add (Val.add (rs PC) Vone) Vone).
+ rewrite <- H5. reflexivity.
assert (AG3: agree ms sp rs3).
unfold rs3, rs2; auto 8 with ppcgen.
- assert (WTRA: Val.has_type rs3#LR Tint).
- change rs3#LR with (Val.add (Val.add rs1#PC Vone) Vone).
- rewrite <- H5. exact I.
- generalize (H1 rs3 WTF' TFIND AG3 WTRA).
- intros [rs4 [AG4 [EXF' PC4]]].
- exists rs4. split. auto. split.
- apply exec_trans with E0 rs2 m t. apply exec_one. econstructor.
- eauto. apply functions_transl. eexact H6.
- rewrite find_instr_tail. rewrite H7. reflexivity.
- simpl. rewrite <- (ireg_val ms sp rs1); auto.
- apply exec_trans with E0 rs3 m t. apply exec_one. econstructor.
- unfold rs2, nextinstr. rewrite Pregmap.gss.
- rewrite Pregmap.gso. rewrite <- H5. simpl. reflexivity.
- discriminate. apply functions_transl. eexact H6.
- rewrite find_instr_tail. rewrite CT1. reflexivity.
- simpl. replace (rs2 CTR) with (ms m0). reflexivity.
- unfold rs2. rewrite nextinstr_inv. rewrite Pregmap.gss.
- auto. discriminate.
- exact EXF'. traceEq. traceEq.
- rewrite PC4. unfold rs3. rewrite Pregmap.gso. rewrite Pregmap.gss.
- unfold rs2, nextinstr. rewrite Pregmap.gss. rewrite Pregmap.gso.
- rewrite <- H5. simpl. constructor. auto. auto.
- discriminate. discriminate.
+ left; exists (State rs3 m); split.
+ apply plus_left with E0 (State rs2 m) E0.
+ econstructor. eauto. apply functions_transl. eexact H0.
+ eapply find_instr_tail. eauto.
+ simpl. rewrite <- (ireg_val ms sp rs); auto.
+ apply star_one. econstructor.
+ change (rs2 PC) with (Val.add (rs PC) Vone). rewrite <- H5.
+ simpl. auto.
+ apply functions_transl. eexact H0.
+ eapply find_instr_tail. eauto.
+ simpl. reflexivity.
+ traceEq.
+ econstructor; eauto.
+ econstructor; eauto with coqlib.
+ rewrite RA_EQ. econstructor; eauto.
(* Direct call *)
- caseEq (Genv.find_symbol ge i). intros fblock FINDS.
- rewrite FINDS in H.
generalize (code_tail_next_int _ _ _ _ NOOV H7). intro CT1.
- set (rs2 := rs1 #LR <- (Val.add rs1#PC Vone) #PC <- (symbol_offset tge i Int.zero)).
- assert (TFIND: Genv.find_funct ge (rs2#PC) = Some f').
- unfold rs2. rewrite Pregmap.gss.
- unfold symbol_offset. rewrite symbols_preserved.
- rewrite FINDS.
- rewrite Genv.find_funct_find_funct_ptr. assumption.
+ set (rs2 := rs #LR <- (Val.add rs#PC Vone) #PC <- (symbol_offset tge i Int.zero)).
+ assert (ATPC: rs2 PC = Vptr f' Int.zero).
+ change (rs2 PC) with (symbol_offset tge i Int.zero).
+ unfold symbol_offset. rewrite symbols_preserved. rewrite H. auto.
+ exploit return_address_offset_correct; eauto. constructor; eauto.
+ intro RA_EQ.
+ assert (ATLR: rs2 LR = Vptr fb ra).
+ rewrite RA_EQ.
+ change (rs2 LR) with (Val.add (rs PC) Vone).
+ rewrite <- H5. reflexivity.
assert (AG2: agree ms sp rs2).
unfold rs2; auto 8 with ppcgen.
- assert (WTRA: Val.has_type rs2#LR Tint).
- change rs2#LR with (Val.add rs1#PC Vone).
- rewrite <- H5. exact I.
- generalize (H1 rs2 WTF' TFIND AG2 WTRA).
- intros [rs3 [AG3 [EXF' PC3]]].
- exists rs3. split. auto. split.
- apply exec_trans with E0 rs2 m t. apply exec_one. econstructor.
- eauto. apply functions_transl. eexact H6.
- rewrite find_instr_tail. rewrite H7. reflexivity.
- simpl. reflexivity.
- exact EXF'. traceEq.
- rewrite PC3. unfold rs2. rewrite Pregmap.gso. rewrite Pregmap.gss.
- rewrite <- H5. simpl. constructor. auto. auto.
- discriminate.
- intro FINDS. rewrite FINDS in H. discriminate.
+ left; exists (State rs2 m); split.
+ apply plus_one. econstructor.
+ eauto.
+ apply functions_transl. eexact H0.
+ eapply find_instr_tail. eauto.
+ simpl. reflexivity.
+ econstructor; eauto with coqlib.
+ econstructor; eauto with coqlib.
+ rewrite RA_EQ. econstructor; eauto.
+Qed.
+
+Lemma exec_Mtailcall_prop:
+ forall (s : list stackframe) (fb stk : block) (soff : int)
+ (sig : signature) (ros : mreg + ident) (c : list Mach.instruction)
+ (ms : Mach.regset) (m : mem) (f' : block),
+ find_function_ptr ge ros ms = Some f' ->
+ load_stack m (Vptr stk soff) Tint (Int.repr 0) = Some (parent_sp s) ->
+ load_stack m (Vptr stk soff) Tint (Int.repr 12) = Some (parent_ra s) ->
+ exec_instr_prop
+ (Machconcr.State s fb (Vptr stk soff) (Mtailcall sig ros :: c) ms m) E0
+ (Callstate s f' ms (free m stk)).
+Proof.
+ intros; red; intros; inv MS.
+ generalize (wt_function_instrs _ WTF _ (INCL _ (in_eq _ _))).
+ intro WTI. inversion WTI.
+ inversion AT. subst b f0 c0.
+ assert (NOOV: code_size (transl_function f) <= Int.max_unsigned).
+ eapply functions_transl_no_overflow; eauto.
+ destruct ros; simpl in H; simpl in H8.
+ (* Indirect call *)
+ set (rs2 := nextinstr (rs#CTR <- (ms m0))).
+ set (rs3 := nextinstr (rs2#GPR2 <- (parent_ra s))).
+ set (rs4 := nextinstr (rs3#LR <- (parent_ra s))).
+ set (rs5 := nextinstr (rs4#GPR1 <- (parent_sp s))).
+ set (rs6 := rs5#PC <- (rs5 CTR)).
+ assert (exec_straight tge (transl_function f)
+ (transl_code (Mtailcall sig (inl ident m0) :: c)) rs m
+ (Pbctr :: transl_code c) rs5 (free m stk)).
+ simpl. apply exec_straight_step with rs2 m.
+ simpl. rewrite <- (ireg_val _ _ _ _ AG H5). reflexivity. reflexivity.
+ apply exec_straight_step with rs3 m.
+ simpl. unfold load1. rewrite gpr_or_zero_not_zero. unfold const_low.
+ change (rs2 GPR1) with (rs GPR1). rewrite <- (sp_val _ _ _ AG).
+ simpl. unfold load_stack in H1. simpl in H1. rewrite H1.
+ reflexivity. discriminate. reflexivity.
+ apply exec_straight_step with rs4 m.
+ simpl. reflexivity. reflexivity.
+ apply exec_straight_one.
+ simpl. change (rs4 GPR1) with (rs GPR1). rewrite <- (sp_val _ _ _ AG).
+ unfold load_stack in H0; simpl in H0. rewrite Int.add_zero in H0.
+ simpl. rewrite H0. reflexivity. reflexivity.
+ left; exists (State rs6 (free m stk)); split.
+ (* execution *)
+ eapply plus_right'. eapply exec_straight_exec; eauto.
+ econstructor.
+ change (rs5 PC) with (Val.add (Val.add (Val.add (Val.add (rs PC) Vone) Vone) Vone) Vone).
+ rewrite <- H6; simpl. eauto.
+ eapply functions_transl; eauto.
+ eapply find_instr_tail.
+ repeat (eapply code_tail_next_int; auto). eauto.
+ simpl. reflexivity. traceEq.
+ (* match states *)
+ econstructor; eauto.
+ assert (AG4: agree ms (Vptr stk soff) rs4).
+ unfold rs4, rs3, rs2; auto 10 with ppcgen.
+ assert (AG5: agree ms (parent_sp s) rs5).
+ unfold rs5. apply agree_nextinstr.
+ split. reflexivity. intros. inv AG4. rewrite H11.
+ rewrite Pregmap.gso; auto with ppcgen.
+ unfold rs6; auto with ppcgen.
+ change (rs6 PC) with (ms m0).
+ generalize H. destruct (ms m0); try congruence.
+ predSpec Int.eq Int.eq_spec i Int.zero; intros; congruence.
+ (* direct call *)
+ set (rs2 := nextinstr (rs#GPR2 <- (parent_ra s))).
+ set (rs3 := nextinstr (rs2#LR <- (parent_ra s))).
+ set (rs4 := nextinstr (rs3#GPR1 <- (parent_sp s))).
+ set (rs5 := rs4#PC <- (Vptr f' Int.zero)).
+ assert (exec_straight tge (transl_function f)
+ (transl_code (Mtailcall sig (inr mreg i) :: c)) rs m
+ (Pbs i :: transl_code c) rs4 (free m stk)).
+ simpl. apply exec_straight_step with rs2 m.
+ simpl. unfold load1. rewrite gpr_or_zero_not_zero. unfold const_low.
+ rewrite <- (sp_val _ _ _ AG).
+ simpl. unfold load_stack in H1. simpl in H1. rewrite H1.
+ reflexivity. discriminate. reflexivity.
+ apply exec_straight_step with rs3 m.
+ simpl. reflexivity. reflexivity.
+ apply exec_straight_one.
+ simpl. change (rs3 GPR1) with (rs GPR1). rewrite <- (sp_val _ _ _ AG).
+ unfold load_stack in H0; simpl in H0. rewrite Int.add_zero in H0.
+ simpl. rewrite H0. reflexivity. reflexivity.
+ left; exists (State rs5 (free m stk)); split.
+ (* execution *)
+ eapply plus_right'. eapply exec_straight_exec; eauto.
+ econstructor.
+ change (rs4 PC) with (Val.add (Val.add (Val.add (rs PC) Vone) Vone) Vone).
+ rewrite <- H6; simpl. eauto.
+ eapply functions_transl; eauto.
+ eapply find_instr_tail.
+ repeat (eapply code_tail_next_int; auto). eauto.
+ simpl. unfold symbol_offset. rewrite symbols_preserved. rewrite H.
+ reflexivity. traceEq.
+ (* match states *)
+ econstructor; eauto.
+ assert (AG3: agree ms (Vptr stk soff) rs3).
+ unfold rs3, rs2; auto 10 with ppcgen.
+ assert (AG4: agree ms (parent_sp s) rs4).
+ unfold rs4. apply agree_nextinstr.
+ split. reflexivity. intros. inv AG3. rewrite H11.
+ rewrite Pregmap.gso; auto with ppcgen.
+ unfold rs5; auto with ppcgen.
Qed.
Lemma exec_Malloc_prop:
- forall (f : function) (sp : val) (c : list Mach.instruction)
- (ms : Mach.regset) (m : mem) (sz : int) (m' : mem) (blk : block),
+ forall (s : list stackframe) (fb : block) (sp : val)
+ (c : list Mach.instruction) (ms : mreg -> val) (m : mem) (sz : int)
+ (m' : mem) (blk : block),
ms Conventions.loc_alloc_argument = Vint sz ->
- Mem.alloc m 0 (Int.signed sz) = (m', blk) ->
- exec_instr_prop f sp (Malloc :: c) ms m E0 c
- (Regmap.set Conventions.loc_alloc_result (Vptr blk Int.zero) ms) m'.
+ alloc m 0 (Int.signed sz) = (m', blk) ->
+ exec_instr_prop (Machconcr.State s fb sp (Malloc :: c) ms m) E0
+ (Machconcr.State s fb sp c
+ (Regmap.set (Conventions.loc_alloc_result) (Vptr blk Int.zero) ms) m').
Proof.
- intros; red; intros.
- eapply exec_straight_exec_prop; eauto.
+ intros; red; intros; inv MS.
+ left; eapply exec_straight_steps; eauto with coqlib.
simpl. eapply transl_alloc_correct; eauto.
Qed.
Lemma exec_Mgoto_prop:
- forall (f : function) (sp : val) (lbl : Mach.label)
- (c : list Mach.instruction) (ms : Mach.regset) (m : mem)
- (c' : Mach.code),
- Mach.find_label lbl (fn_code f) = Some c' ->
- exec_instr_prop f sp (Mgoto lbl :: c) ms m E0 c' ms m.
+ forall (s : list stackframe) (fb : block) (f : function) (sp : val)
+ (lbl : Mach.label) (c : list Mach.instruction) (ms : Mach.regset)
+ (m : mem) (c' : Mach.code),
+ Genv.find_funct_ptr ge fb = Some (Internal f) ->
+ Mach.find_label lbl (fn_code f) = Some c' ->
+ exec_instr_prop (Machconcr.State s fb sp (Mgoto lbl :: c) ms m) E0
+ (Machconcr.State s fb sp c' ms m).
Proof.
- intros; red; intros.
- inversion AT.
- generalize (find_label_goto_label f lbl rs1 m _ _ _ H1 (sym_equal H0) H).
+ intros; red; intros; inv MS.
+ assert (f0 = f) by congruence. subst f0.
+ inv AT. simpl in H3.
+ generalize (find_label_goto_label f lbl rs m _ _ _ FIND (sym_equal H1) H0).
intros [rs2 [GOTO [AT2 INV]]].
- exists rs2. split. apply agree_exten_2 with rs1; auto.
- split. inversion AT. apply exec_one. econstructor; eauto.
- apply functions_transl; eauto.
- rewrite find_instr_tail. rewrite H7. simpl. reflexivity.
- simpl. rewrite GOTO. auto. auto.
+ left; exists (State rs2 m); split.
+ apply plus_one. econstructor; eauto.
+ apply functions_transl; eauto.
+ eapply find_instr_tail; eauto.
+ simpl; auto.
+ econstructor; eauto.
+ eapply Mach.find_label_incl; eauto.
+ apply agree_exten_2 with rs; auto.
Qed.
Lemma exec_Mcond_true_prop:
- forall (f : function) (sp : val) (cond : condition)
- (args : list mreg) (lbl : Mach.label) (c : list Mach.instruction)
- (ms: Mach.regset) (m : mem) (c' : Mach.code),
- eval_condition cond ms ## args = Some true ->
- Mach.find_label lbl (fn_code f) = Some c' ->
- exec_instr_prop f sp (Mcond cond args lbl :: c) ms m E0 c' ms m.
+ forall (s : list stackframe) (fb : block) (f : function) (sp : val)
+ (cond : condition) (args : list mreg) (lbl : Mach.label)
+ (c : list Mach.instruction) (ms : mreg -> val) (m : mem)
+ (c' : Mach.code),
+ eval_condition cond ms ## args m = Some true ->
+ Genv.find_funct_ptr ge fb = Some (Internal f) ->
+ Mach.find_label lbl (fn_code f) = Some c' ->
+ exec_instr_prop (Machconcr.State s fb sp (Mcond cond args lbl :: c) ms m) E0
+ (Machconcr.State s fb sp c' ms m).
Proof.
- intros; red; intros.
+ intros; red; intros; inv MS. assert (f0 = f) by congruence. subst f0.
generalize (wt_function_instrs _ WTF _ (INCL _ (in_eq _ _))).
- intro WTI. inversion WTI.
+ intro WTI. inv WTI.
pose (k1 :=
if snd (crbit_for_cond cond)
then Pbt (fst (crbit_for_cond cond)) lbl :: transl_code c
else Pbf (fst (crbit_for_cond cond)) lbl :: transl_code c).
generalize (transl_cond_correct tge (transl_function f)
- cond args k1 ms sp rs1 m true H2 AG H).
+ cond args k1 ms sp rs m true H3 AG H).
simpl. intros [rs2 [EX [RES AG2]]].
- inversion AT.
- generalize (functions_transl _ _ H6); intro FN.
- generalize (functions_transl_no_overflow _ _ H6); intro NOOV.
- simpl in H7.
- generalize (exec_straight_steps_2 _ _ _ _ _ _ _ EX
- NOOV _ _ (sym_equal H5) FN H7).
+ inv AT. simpl in H5.
+ generalize (functions_transl _ _ H4); intro FN.
+ generalize (functions_transl_no_overflow _ _ H4); intro NOOV.
+ exploit exec_straight_steps_2; eauto.
intros [ofs' [PC2 CT2]].
- generalize (find_label_goto_label f lbl rs2 m _ _ _ H6 PC2 H0).
+ generalize (find_label_goto_label f lbl rs2 m _ _ _ FIND PC2 H1).
intros [rs3 [GOTO [AT3 INV3]]].
- exists rs3. split.
- apply agree_exten_2 with rs2; auto.
- split. eapply exec_trans.
+ left; exists (State rs3 m); split.
+ eapply plus_right'.
eapply exec_straight_steps_1; eauto.
caseEq (snd (crbit_for_cond cond)); intro ISSET; rewrite ISSET in RES.
- apply exec_one. econstructor; eauto.
- rewrite find_instr_tail. rewrite CT2. unfold k1. rewrite ISSET. reflexivity.
+ econstructor; eauto.
+ eapply find_instr_tail. unfold k1 in CT2; rewrite ISSET in CT2. eauto.
simpl. rewrite RES. simpl. auto.
- apply exec_one. econstructor; eauto.
- rewrite find_instr_tail. rewrite CT2. unfold k1. rewrite ISSET. reflexivity.
+ econstructor; eauto.
+ eapply find_instr_tail. unfold k1 in CT2; rewrite ISSET in CT2. eauto.
simpl. rewrite RES. simpl. auto.
- traceEq. auto.
+ traceEq.
+ econstructor; eauto.
+ eapply Mach.find_label_incl; eauto.
+ apply agree_exten_2 with rs2; auto.
Qed.
Lemma exec_Mcond_false_prop:
- forall (f : function) (sp : val) (cond : condition)
- (args : list mreg) (lbl : Mach.label) (c : list Mach.instruction)
- (ms : Mach.regset) (m : mem),
- eval_condition cond ms ## args = Some false ->
- exec_instr_prop f sp (Mcond cond args lbl :: c) ms m E0 c ms m.
+ forall (s : list stackframe) (fb : block) (sp : val)
+ (cond : condition) (args : list mreg) (lbl : Mach.label)
+ (c : list Mach.instruction) (ms : mreg -> val) (m : mem),
+ eval_condition cond ms ## args m = Some false ->
+ exec_instr_prop (Machconcr.State s fb sp (Mcond cond args lbl :: c) ms m) E0
+ (Machconcr.State s fb sp c ms m).
Proof.
- intros; red; intros.
+ intros; red; intros; inv MS.
generalize (wt_function_instrs _ WTF _ (INCL _ (in_eq _ _))).
intro WTI. inversion WTI.
pose (k1 :=
@@ -979,12 +1152,11 @@ Proof.
then Pbt (fst (crbit_for_cond cond)) lbl :: transl_code c
else Pbf (fst (crbit_for_cond cond)) lbl :: transl_code c).
generalize (transl_cond_correct tge (transl_function f)
- cond args k1 ms sp rs1 m false H1 AG H).
+ cond args k1 ms sp rs m false H1 AG H).
simpl. intros [rs2 [EX [RES AG2]]].
- exists (nextinstr rs2).
- split. auto with ppcgen.
- eapply exec_straight_steps; eauto.
- eapply exec_straight_trans. eexact EX.
+ left; eapply exec_straight_steps; eauto with coqlib.
+ exists (nextinstr rs2); split.
+ simpl. eapply exec_straight_trans. eexact EX.
caseEq (snd (crbit_for_cond cond)); intro ISSET; rewrite ISSET in RES.
unfold k1; rewrite ISSET; apply exec_straight_one.
simpl. rewrite RES. reflexivity.
@@ -992,114 +1164,110 @@ Proof.
unfold k1; rewrite ISSET; apply exec_straight_one.
simpl. rewrite RES. reflexivity.
reflexivity.
+ auto with ppcgen.
Qed.
-Lemma exec_instr_incl:
- forall f sp c rs m t c' rs' m',
- Mach.exec_instr ge f sp c rs m t c' rs' m' ->
- incl c f.(fn_code) -> incl c' f.(fn_code).
+Lemma exec_Mreturn_prop:
+ forall (s : list stackframe) (fb stk : block) (soff : int)
+ (c : list Mach.instruction) (ms : Mach.regset) (m : mem),
+ load_stack m (Vptr stk soff) Tint (Int.repr 0) = Some (parent_sp s) ->
+ load_stack m (Vptr stk soff) Tint (Int.repr 12) = Some (parent_ra s) ->
+ exec_instr_prop (Machconcr.State s fb (Vptr stk soff) (Mreturn :: c) ms m) E0
+ (Returnstate s ms (free m stk)).
Proof.
- induction 1; intros; eauto with coqlib.
- eapply incl_find_label; eauto.
- eapply incl_find_label; eauto.
-Qed.
-
-Lemma exec_instrs_incl:
- forall f sp c rs m t c' rs' m',
- Mach.exec_instrs ge f sp c rs m t c' rs' m' ->
- incl c f.(fn_code) -> incl c' f.(fn_code).
-Proof.
- induction 1; intros.
- auto.
- eapply exec_instr_incl; eauto.
- eauto.
-Qed.
-
-Lemma exec_refl_prop:
- forall (f : function) (sp : val) (c : Mach.code) (ms : Mach.regset)
- (m : mem), exec_instr_prop f sp c ms m E0 c ms m.
-Proof.
- intros; red; intros.
- exists rs1. split. auto. split. apply exec_refl. auto.
-Qed.
-
-Lemma exec_one_prop:
- forall (f : function) (sp : val) (c : Mach.code) (ms : Mach.regset)
- (m : mem) (t: trace) (c' : Mach.code) (ms' : Mach.regset) (m' : mem),
- Mach.exec_instr ge f sp c ms m t c' ms' m' ->
- exec_instr_prop f sp c ms m t c' ms' m' ->
- exec_instr_prop f sp c ms m t c' ms' m'.
-Proof.
- auto.
+ intros; red; intros; inv MS.
+ set (rs2 := nextinstr (rs#GPR2 <- (parent_ra s))).
+ set (rs3 := nextinstr (rs2#LR <- (parent_ra s))).
+ set (rs4 := nextinstr (rs3#GPR1 <- (parent_sp s))).
+ set (rs5 := rs4#PC <- (parent_ra s)).
+ assert (exec_straight tge (transl_function f)
+ (transl_code (Mreturn :: c)) rs m
+ (Pblr :: transl_code c) rs4 (free m stk)).
+ simpl. apply exec_straight_three with rs2 m rs3 m.
+ simpl. unfold load1. rewrite gpr_or_zero_not_zero. unfold const_low.
+ unfold load_stack in H0. simpl in H0.
+ rewrite <- (sp_val _ _ _ AG). simpl. rewrite H0.
+ reflexivity. discriminate.
+ unfold rs3. change (parent_ra s) with rs2#GPR2. reflexivity.
+ simpl. change (rs3 GPR1) with (rs GPR1). rewrite <- (sp_val _ _ _ AG).
+ simpl.
+ unfold load_stack in H. simpl in H. rewrite Int.add_zero in H.
+ rewrite H. reflexivity.
+ reflexivity. reflexivity. reflexivity.
+ left; exists (State rs5 (free m stk)); split.
+ (* execution *)
+ apply plus_right' with E0 (State rs4 (free m stk)) E0.
+ eapply exec_straight_exec; eauto.
+ inv AT. econstructor.
+ change (rs4 PC) with (Val.add (Val.add (Val.add (rs PC) Vone) Vone) Vone).
+ rewrite <- H2. simpl. eauto.
+ apply functions_transl; eauto.
+ generalize (functions_transl_no_overflow _ _ H3); intro NOOV.
+ simpl in H4. eapply find_instr_tail.
+ eapply code_tail_next_int; auto.
+ eapply code_tail_next_int; auto.
+ eapply code_tail_next_int; eauto.
+ reflexivity. traceEq.
+ (* match states *)
+ econstructor; eauto.
+ assert (AG3: agree ms (Vptr stk soff) rs3).
+ unfold rs3, rs2; auto 10 with ppcgen.
+ assert (AG4: agree ms (parent_sp s) rs4).
+ split. reflexivity. intros. unfold rs4.
+ rewrite nextinstr_inv. rewrite Pregmap.gso.
+ elim AG3; auto. auto with ppcgen. auto with ppcgen.
+ unfold rs5; auto with ppcgen.
Qed.
-Lemma exec_trans_prop:
- forall (f : function) (sp : val) (c1 : Mach.code) (ms1 : Mach.regset)
- (m1 : mem) (t1: trace) (c2 : Mach.code) (ms2 : Mach.regset) (m2 : mem)
- (t2: trace) (c3 : Mach.code) (ms3 : Mach.regset) (m3 : mem) (t3: trace),
- exec_instrs ge f sp c1 ms1 m1 t1 c2 ms2 m2 ->
- exec_instr_prop f sp c1 ms1 m1 t1 c2 ms2 m2 ->
- exec_instrs ge f sp c2 ms2 m2 t2 c3 ms3 m3 ->
- exec_instr_prop f sp c2 ms2 m2 t2 c3 ms3 m3 ->
- t3 = t1 ** t2 ->
- exec_instr_prop f sp c1 ms1 m1 t3 c3 ms3 m3.
-Proof.
- intros; red; intros.
- generalize (H0 rs1 WTF INCL AT AG).
- intros [rs2 [AG2 [EX2 AT2]]].
- generalize (exec_instrs_incl _ _ _ _ _ _ _ _ _ H INCL). intro INCL2.
- generalize (H2 rs2 WTF INCL2 AT2 AG2).
- intros [rs3 [AG3 [EX3 AT3]]].
- exists rs3. split. auto. split. eapply exec_trans; eauto. auto.
-Qed.
+Hypothesis wt_prog: wt_program prog.
-Lemma exec_function_body_prop_:
- forall (f : function) (parent ra : val) (ms : Mach.regset) (m : mem)
- (t: trace) (ms' : Mach.regset) (m1 m2 m3 m4 : mem) (stk : block)
- (c : list Mach.instruction),
- alloc m (- fn_framesize f)
- (align_16_top (- fn_framesize f) (fn_stacksize f)) = (m1, stk) ->
- let sp := Vptr stk (Int.repr (- fn_framesize f)) in
- store_stack m1 sp Tint (Int.repr 0) parent = Some m2 ->
- store_stack m2 sp Tint (Int.repr 12) ra = Some m3 ->
- exec_instrs ge f sp (fn_code f) ms m3 t (Mreturn :: c) ms' m4 ->
- exec_instr_prop f sp (fn_code f) ms m3 t (Mreturn :: c) ms' m4 ->
- load_stack m4 sp Tint (Int.repr 0) = Some parent ->
- load_stack m4 sp Tint (Int.repr 12) = Some ra ->
- exec_function_body_prop f parent ra ms m t ms' (free m4 stk).
+Lemma exec_function_internal_prop:
+ forall (s : list stackframe) (fb : block) (ms : Mach.regset)
+ (m : mem) (f : function) (m1 m2 m3 : mem) (stk : block),
+ Genv.find_funct_ptr ge fb = Some (Internal f) ->
+ alloc m (- fn_framesize f)
+ (align_16_top (- fn_framesize f) (fn_stacksize f)) = (m1, stk) ->
+ let sp := Vptr stk (Int.repr (- fn_framesize f)) in
+ store_stack m1 sp Tint (Int.repr 0) (parent_sp s) = Some m2 ->
+ store_stack m2 sp Tint (Int.repr 12) (parent_ra s) = Some m3 ->
+ exec_instr_prop (Machconcr.Callstate s fb ms m) E0
+ (Machconcr.State s fb sp (fn_code f) ms m3).
Proof.
- intros; red; intros.
- generalize (Genv.find_funct_inv AT). intros [b EQPC].
- generalize AT. rewrite EQPC. rewrite Genv.find_funct_find_funct_ptr. intro FN.
- generalize (functions_transl_no_overflow _ _ FN); intro NOOV.
- set (rs2 := nextinstr (rs1#GPR1 <- sp #GPR2 <- Vundef)).
- set (rs3 := nextinstr (rs2#GPR2 <- ra)).
+ intros; red; intros; inv MS.
+ assert (WTF: wt_function f).
+ generalize (Genv.find_funct_ptr_prop wt_fundef wt_prog H); intro TY.
+ inversion TY; auto.
+ exploit functions_transl; eauto. intro TFIND.
+ generalize (functions_transl_no_overflow _ _ H); intro NOOV.
+ set (rs2 := nextinstr (rs#GPR1 <- sp #GPR2 <- Vundef)).
+ set (rs3 := nextinstr (rs2#GPR2 <- (parent_ra s))).
set (rs4 := nextinstr rs3).
- assert (exec_straight tge (transl_function f)
- (transl_function f) rs1 m
- (transl_code (fn_code f)) rs4 m3).
+ (* Execution of function prologue *)
+ assert (EXEC_PROLOGUE:
+ exec_straight tge (transl_function f)
+ (transl_function f) rs m
+ (transl_code (fn_code f)) rs4 m3).
unfold transl_function at 2.
apply exec_straight_three with rs2 m2 rs3 m2.
- unfold exec_instr. rewrite H. fold sp.
- generalize H0. unfold store_stack. change (Vint (Int.repr 0)) with Vzero.
+ unfold exec_instr. rewrite H0. fold sp.
+ generalize H1. unfold store_stack. change (Vint (Int.repr 0)) with Vzero.
replace (Val.add sp Vzero) with sp. simpl chunk_of_type.
- rewrite (sp_val _ _ _ AG). intro. rewrite H6. clear H6.
+ rewrite (sp_val _ _ _ AG). intro EQ; rewrite EQ; clear EQ.
reflexivity. unfold sp. simpl. rewrite Int.add_zero. reflexivity.
- simpl. replace (rs2 LR) with ra. reflexivity.
+ simpl. change (rs2 LR) with (rs LR). rewrite ATLR. reflexivity.
simpl. unfold store1. rewrite gpr_or_zero_not_zero.
- unfold const_low. replace (rs3 GPR1) with sp. replace (rs3 GPR2) with ra.
- unfold store_stack in H1. simpl chunk_of_type in H1. rewrite H1. reflexivity.
- reflexivity. reflexivity. discriminate.
- reflexivity. reflexivity. reflexivity.
- assert (AT2: transl_code_at_pc rs4#PC f f.(fn_code)).
- change (rs4 PC) with (Val.add (Val.add (Val.add (rs1 PC) Vone) Vone) Vone).
- rewrite EQPC. simpl. constructor. auto.
+ unfold const_low. change (rs3 GPR1) with sp. change (rs3 GPR2) with (parent_ra s).
+ unfold store_stack in H2. simpl chunk_of_type in H2. rewrite H2. reflexivity.
+ discriminate. reflexivity. reflexivity. reflexivity.
+ (* Agreement at end of prologue *)
+ assert (AT4: transl_code_at_pc rs4#PC fb f f.(fn_code)).
+ change (rs4 PC) with (Val.add (Val.add (Val.add (rs PC) Vone) Vone) Vone).
+ rewrite ATPC. simpl. constructor. auto.
eapply code_tail_next_int; auto.
eapply code_tail_next_int; auto.
eapply code_tail_next_int; auto.
- unfold Int.zero. rewrite Int.unsigned_repr.
- rewrite code_tail_zero. unfold transl_function. reflexivity.
- compute. intuition congruence.
+ change (Int.unsigned Int.zero) with 0.
+ unfold transl_function. constructor.
assert (AG2: agree ms sp rs2).
split. reflexivity.
intros. unfold rs2. rewrite nextinstr_inv.
@@ -1107,114 +1275,52 @@ Proof.
auto with ppcgen. auto with ppcgen. auto with ppcgen.
assert (AG4: agree ms sp rs4).
unfold rs4, rs3; auto with ppcgen.
- generalize (H3 rs4 WTF (incl_refl _) AT2 AG4).
- intros [rs5 [AG5 [EXB AT5]]].
- set (rs6 := nextinstr (rs5#GPR2 <- ra)).
- set (rs7 := nextinstr (rs6#LR <- ra)).
- set (rs8 := nextinstr (rs7#GPR1 <- parent)).
- set (rs9 := rs8#PC <- ra).
- assert (exec_straight tge (transl_function f)
- (transl_code (Mreturn :: c)) rs5 m4
- (Pblr :: transl_code c) rs8 (free m4 stk)).
- simpl. apply exec_straight_three with rs6 m4 rs7 m4.
- simpl. unfold load1. rewrite gpr_or_zero_not_zero. unfold const_low.
- unfold load_stack in H5. simpl in H5.
- rewrite <- (sp_val _ _ _ AG5). simpl. rewrite H5.
- reflexivity. discriminate.
- unfold rs7. change ra with rs6#GPR2. reflexivity.
- unfold exec_instr. generalize H4. unfold load_stack.
- replace (Val.add sp (Vint (Int.repr 0))) with sp.
- simpl chunk_of_type. intro. change rs7#GPR1 with rs5#GPR1.
- rewrite <- (sp_val _ _ _ AG5). rewrite H7.
- unfold sp. reflexivity.
- unfold sp. simpl. rewrite Int.add_zero. reflexivity.
- reflexivity. reflexivity. reflexivity.
- exists rs9. split.
- (* agreement *)
- assert (AG7: agree ms' sp rs7).
- unfold rs7, rs6; auto 10 with ppcgen.
- assert (AG8: agree ms' parent rs8).
- split. reflexivity. intros. unfold rs8.
- rewrite nextinstr_inv. rewrite Pregmap.gso.
- elim AG7; auto. auto with ppcgen. auto with ppcgen.
- unfold rs9; auto with ppcgen.
+ left; exists (State rs4 m3); split.
(* execution *)
- split. apply exec_trans with E0 rs4 m3 t.
- eapply exec_straight_steps_1; eauto.
- apply functions_transl; auto.
- apply exec_trans with t rs5 m4 E0. assumption.
- inversion AT5.
- apply exec_trans with E0 rs8 (free m4 stk) E0.
eapply exec_straight_steps_1; eauto.
- apply functions_transl; auto.
- apply exec_one. econstructor.
- change rs8#PC with (Val.add (Val.add (Val.add rs5#PC Vone) Vone) Vone).
- rewrite <- H8. simpl. reflexivity.
- apply functions_transl; eauto.
- assert (code_tail (Int.unsigned (Int.add (Int.add (Int.add ofs Int.one) Int.one) Int.one))
- (transl_function f) = Pblr :: transl_code c).
- eapply code_tail_next_int; auto.
- eapply code_tail_next_int; auto.
- eapply code_tail_next_int; auto.
- rewrite H10. simpl. reflexivity.
- rewrite find_instr_tail. rewrite H13.
- reflexivity.
- reflexivity.
- traceEq. traceEq. traceEq.
- (* LR preservation *)
- change rs9#PC with ra. auto.
+ change (Int.unsigned Int.zero) with 0. constructor.
+ (* match states *)
+ econstructor; eauto with coqlib.
Qed.
-Lemma exec_function_internal_prop:
- forall (f : function) (parent : val) (ms : Mach.regset) (m : mem)
- (t: trace) (ms' : Mach.regset) (m' : mem),
- (forall ra : val,
- Val.has_type ra Tint ->
- exec_function_body ge f parent ra ms m t ms' m') ->
- (forall ra : val, Val.has_type ra Tint ->
- exec_function_body_prop f parent ra ms m t ms' m') ->
- exec_function_prop (Internal f) parent ms m t ms' m'.
+Lemma exec_function_external_prop:
+ forall (s : list stackframe) (fb : block) (ms : Mach.regset)
+ (m : mem) (t0 : trace) (ms' : RegEq.t -> val)
+ (ef : external_function) (args : list val) (res : val),
+ Genv.find_funct_ptr ge fb = Some (External ef) ->
+ event_match ef args t0 res ->
+ Machconcr.extcall_arguments ms m (parent_sp s) (ef_sig ef) args ->
+ ms' = Regmap.set (Conventions.loc_result (ef_sig ef)) res ms ->
+ exec_instr_prop (Machconcr.Callstate s fb ms m)
+ t0 (Machconcr.Returnstate s ms' m).
Proof.
- intros; red; intros.
- inversion WTF. subst f0.
- apply (H0 rs1#LR WTRA rs1 WTRA (refl_equal _) H2 AT AG).
+ intros; red; intros; inv MS.
+ exploit functions_translated; eauto.
+ intros [tf [A B]]. simpl in B. inv B.
+ left; exists (State (rs#(loc_external_result (ef_sig ef)) <- res #PC <- (rs LR))
+ m); split.
+ apply plus_one. eapply exec_step_external; eauto.
+ eapply extcall_arguments_match; eauto.
+ econstructor; eauto.
+ rewrite loc_external_result_match. auto with ppcgen.
Qed.
-Lemma exec_function_external_prop:
- forall (ef : external_function) (parent : val) (args : list val)
- (res : val) (ms1 ms2: Mach.regset) (m : mem)
- (t : trace),
- event_match ef args t res ->
- Mach.extcall_arguments ms1 m parent ef.(ef_sig) args ->
- ms2 = Regmap.set (Conventions.loc_result (ef_sig ef)) res ms1 ->
- exec_function_prop (External ef) parent ms1 m t ms2 m.
+Lemma exec_return_prop:
+ forall (s : list stackframe) (fb : block) (sp ra : val)
+ (c : Mach.code) (ms : Mach.regset) (m : mem),
+ exec_instr_prop (Machconcr.Returnstate (Stackframe fb sp ra c :: s) ms m) E0
+ (Machconcr.State s fb sp c ms m).
Proof.
- intros; red; intros.
- destruct (Genv.find_funct_inv AT) as [b EQ].
- rewrite EQ in AT. rewrite Genv.find_funct_find_funct_ptr in AT.
- exists (rs1#(loc_external_result (ef_sig ef)) <- res #PC <- (rs1 LR)).
- split. rewrite loc_external_result_match. rewrite H1. auto with ppcgen.
- split. apply exec_one. eapply exec_step_external; eauto.
- destruct (functions_translated _ _ AT) as [tf [A B]].
- simpl in B. congruence.
- eapply extcall_arguments_match; eauto.
- reflexivity.
+ intros; red; intros; inv MS. inv STACKS. simpl in *.
+ right. split. omega. split. auto.
+ econstructor; eauto. rewrite ATPC; auto.
Qed.
-(** We then conclude by induction on the structure of the Mach
-execution derivation. *)
-
-Theorem transf_function_correct:
- forall f parent ms m t ms' m',
- Mach.exec_function ge f parent ms m t ms' m' ->
- exec_function_prop f parent ms m t ms' m'.
-Proof
- (Mach.exec_function_ind4 ge
- exec_instr_prop
- exec_instr_prop
- exec_function_body_prop
- exec_function_prop
-
+Theorem transf_instr_correct:
+ forall s1 t s2, Machconcr.step ge s1 t s2 ->
+ exec_instr_prop s1 t s2.
+Proof
+ (Machconcr.step_ind ge exec_instr_prop
exec_Mlabel_prop
exec_Mgetstack_prop
exec_Msetstack_prop
@@ -1223,53 +1329,50 @@ Proof
exec_Mload_prop
exec_Mstore_prop
exec_Mcall_prop
+ exec_Mtailcall_prop
exec_Malloc_prop
exec_Mgoto_prop
exec_Mcond_true_prop
exec_Mcond_false_prop
- exec_refl_prop
- exec_one_prop
- exec_trans_prop
- exec_function_body_prop_
+ exec_Mreturn_prop
exec_function_internal_prop
- exec_function_external_prop).
+ exec_function_external_prop
+ exec_return_prop).
-End PRESERVATION.
+Lemma transf_initial_states:
+ forall st1, Machconcr.initial_state prog st1 ->
+ exists st2, PPC.initial_state tprog st2 /\ match_states st1 st2.
+Proof.
+ intros. inversion H. unfold ge0 in *.
+ econstructor; split.
+ econstructor.
+ replace (symbol_offset (Genv.globalenv tprog) (prog_main tprog) Int.zero)
+ with (Vptr fb Int.zero).
+ rewrite (Genv.init_mem_transf_partial _ _ TRANSF).
+ econstructor; eauto. constructor.
+ split. auto. intros. repeat rewrite Pregmap.gso; auto with ppcgen.
+ unfold symbol_offset.
+ rewrite (transform_partial_program_main _ _ TRANSF).
+ rewrite symbols_preserved. unfold ge; rewrite H0. auto.
+Qed.
+
+Lemma transf_final_states:
+ forall st1 st2 r,
+ match_states st1 st2 -> Machconcr.final_state st1 r -> PPC.final_state st2 r.
+Proof.
+ intros. inv H0. inv H. constructor. auto.
+ rewrite (ireg_val _ _ _ R3 AG) in H1. auto. auto.
+Qed.
Theorem transf_program_correct:
- forall (p: Mach.program) (tp: PPC.program) (t: trace) (r: val),
- wt_program p ->
- transf_program p = Some tp ->
- Mach.exec_program p t r ->
- PPC.exec_program tp t r.
+ forall (beh: program_behavior),
+ Machconcr.exec_program prog beh -> PPC.exec_program tprog beh.
Proof.
- intros.
- destruct H1 as [fptr [f [ms [m [FINDS [FINDF [EX RES]]]]]]].
- assert (WTF: wt_fundef f).
- apply (Genv.find_funct_ptr_prop wt_fundef H FINDF).
- set (ge := Genv.globalenv p) in *.
- set (ms0 := Regmap.init Vundef) in *.
- set (tge := Genv.globalenv tp).
- set (rs0 :=
- (Pregmap.init Vundef) # PC <- (symbol_offset tge tp.(prog_main) Int.zero)
- # LR <- Vzero
- # GPR1 <- (Vptr Mem.nullptr Int.zero)).
- assert (AT: Genv.find_funct ge (rs0 PC) = Some f).
- change (rs0 PC) with (symbol_offset tge tp.(prog_main) Int.zero).
- rewrite (transform_partial_program_main _ _ H0).
- unfold symbol_offset. rewrite (symbols_preserved p tp H0).
- fold ge. rewrite FINDS.
- rewrite Genv.find_funct_find_funct_ptr. exact FINDF.
- assert (AG: agree ms0 (Vptr Mem.nullptr Int.zero) rs0).
- split. reflexivity. intros. unfold rs0.
- repeat (rewrite Pregmap.gso; auto with ppcgen).
- assert (WTRA: Val.has_type (rs0 LR) Tint).
- exact I.
- generalize (transf_function_correct p tp H0 H
- _ _ _ _ _ _ _ EX rs0 WTF AT AG WTRA).
- intros [rs [AG' [EX' RPC]]].
- red. exists rs; exists m.
- split. rewrite (Genv.init_mem_transf_partial _ _ H0). exact EX'.
- split. rewrite RPC. reflexivity. rewrite <- RES.
- change (IR GPR3) with (preg_of R3). elim AG'; auto.
+ unfold Machconcr.exec_program, PPC.exec_program; intros.
+ eapply simulation_star_preservation with (measure := measure); eauto.
+ eexact transf_initial_states.
+ eexact transf_final_states.
+ exact transf_instr_correct.
Qed.
+
+End PRESERVATION.
diff --git a/backend/PPCgenproof1.v b/backend/PPCgenproof1.v
index f9af3c3..1b432c7 100644
--- a/backend/PPCgenproof1.v
+++ b/backend/PPCgenproof1.v
@@ -11,6 +11,7 @@ Require Import Globalenvs.
Require Import Op.
Require Import Locations.
Require Import Mach.
+Require Import Machconcr.
Require Import Machtyping.
Require Import PPC.
Require Import PPCgen.
@@ -448,7 +449,7 @@ Lemma extcall_args_match:
forall tyl iregl fregl ofs args,
(forall r, In r iregl -> mreg_type r = Tint) ->
(forall r, In r fregl -> mreg_type r = Tfloat) ->
- Mach.extcall_args ms m sp (Conventions.loc_arguments_rec tyl iregl fregl ofs) args ->
+ Machconcr.extcall_args ms m sp (Conventions.loc_arguments_rec tyl iregl fregl ofs) args ->
PPC.extcall_args rs m tyl (List.map ireg_of iregl) (List.map freg_of fregl) (4 * ofs) args.
Proof.
induction tyl; intros.
@@ -478,9 +479,7 @@ Proof.
eapply sp_val; eauto.
change (@nil freg) with (freg_of ## nil).
replace (4 * ofs + 8) with (4 * (ofs + 2)) by omega.
- rewrite list_map_drop2.
apply IHtyl; auto.
- intros. apply H0. apply list_drop2_incl. auto.
(* register *)
inversion H2; subst; clear H2. inversion H8; subst; clear H8.
simpl map. econstructor. eapply freg_val; eauto.
@@ -505,13 +504,13 @@ Ltac ElimOrEq :=
Lemma extcall_arguments_match:
forall ms m sp rs sg args,
agree ms sp rs ->
- Mach.extcall_arguments ms m sp sg args ->
+ Machconcr.extcall_arguments ms m sp sg args ->
PPC.extcall_arguments rs m sg args.
Proof.
- unfold Mach.extcall_arguments, PPC.extcall_arguments; intros.
+ unfold Machconcr.extcall_arguments, PPC.extcall_arguments; intros.
change (extcall_args rs m sg.(sig_args)
(List.map ireg_of Conventions.int_param_regs)
- (List.map freg_of Conventions.float_param_regs) (4 * 6) args).
+ (List.map freg_of Conventions.float_param_regs) (4 * 14) args).
eapply extcall_args_match; eauto.
intro; simpl; ElimOrEq; reflexivity.
intro; simpl; ElimOrEq; reflexivity.
@@ -533,9 +532,11 @@ Variable fn: code.
Inductive exec_straight: code -> regset -> mem ->
code -> regset -> mem -> Prop :=
- | exec_straight_refl:
- forall c rs m,
- exec_straight c rs m c rs m
+ | exec_straight_one:
+ forall i1 c rs1 m1 rs2 m2,
+ exec_instr ge fn i1 rs1 m1 = OK rs2 m2 ->
+ rs2#PC = Val.add rs1#PC Vone ->
+ exec_straight (i1 :: c) rs1 m1 c rs2 m2
| exec_straight_step:
forall i c rs1 m1 rs2 m2 c' rs3 m3,
exec_instr ge fn i rs1 m1 = OK rs2 m2 ->
@@ -549,18 +550,9 @@ Lemma exec_straight_trans:
exec_straight c2 rs2 m2 c3 rs3 m3 ->
exec_straight c1 rs1 m1 c3 rs3 m3.
Proof.
- induction 1. auto.
- intro. apply exec_straight_step with rs2 m2; auto.
-Qed.
-
-Lemma exec_straight_one:
- forall i1 c rs1 m1 rs2 m2,
- exec_instr ge fn i1 rs1 m1 = OK rs2 m2 ->
- rs2#PC = Val.add rs1#PC Vone ->
- exec_straight (i1 :: c) rs1 m1 c rs2 m2.
-Proof.
- intros. apply exec_straight_step with rs2 m2. auto. auto.
- apply exec_straight_refl.
+ induction 1; intros.
+ apply exec_straight_step with rs2 m2; auto.
+ apply exec_straight_step with rs2 m2; auto.
Qed.
Lemma exec_straight_two:
@@ -1182,7 +1174,7 @@ Lemma transl_cond_correct:
forall cond args k ms sp rs m b,
map mreg_type args = type_of_condition cond ->
agree ms sp rs ->
- eval_condition cond (map ms args) = Some b ->
+ eval_condition cond (map ms args) m = Some b ->
exists rs',
exec_straight (transl_cond cond args k) rs m k rs' m
/\ rs'#(reg_of_crbit (fst (crbit_for_cond cond))) =
@@ -1191,7 +1183,7 @@ Lemma transl_cond_correct:
else Val.notbool (Val.of_bool b))
/\ agree ms sp rs'.
Proof.
- intros. rewrite <- (eval_condition_weaken _ _ H1).
+ intros. rewrite <- (eval_condition_weaken _ _ _ H1).
apply transl_cond_correct_aux; auto.
Qed.
@@ -1221,12 +1213,12 @@ Lemma transl_op_correct:
forall op args res k ms sp rs m v,
wt_instr (Mop op args res) ->
agree ms sp rs ->
- eval_operation ge sp op (map ms args) = Some v ->
+ eval_operation ge sp op (map ms args) m = Some v ->
exists rs',
exec_straight (transl_op op args res k) rs m k rs' m
/\ agree (Regmap.set res v ms) sp rs'.
Proof.
- intros. rewrite <- (eval_operation_weaken _ _ _ _ H1). clear H1; clear v.
+ intros. rewrite <- (eval_operation_weaken _ _ _ _ _ H1). clear H1; clear v.
inversion H.
(* Omove *)
simpl. exists (nextinstr (rs#(preg_of res) <- (ms r1))).
@@ -1238,19 +1230,9 @@ Proof.
simpl. unfold preg_of. rewrite <- H2. rewrite H5. reflexivity.
auto with ppcgen.
auto with ppcgen.
- (* Oundef *)
- simpl. exists (nextinstr (rs#(preg_of res) <- Vundef)).
- split. caseEq (mreg_type res); intro.
- apply exec_straight_one. simpl.
- unfold preg_of; rewrite H1. reflexivity.
- auto with ppcgen.
- apply exec_straight_one. simpl.
- unfold preg_of; rewrite H1. reflexivity.
- auto with ppcgen.
- auto with ppcgen.
(* Other instructions *)
- clear H1; clear H2; clear H3.
- destruct op; simpl in H6; injection H6; clear H6; intros;
+ clear H1; clear H2; clear H4.
+ destruct op; simpl in H5; injection H5; clear H5; intros;
TypeInv; simpl; try (TranslOpSimpl).
(* Omove again *)
congruence.
@@ -1283,8 +1265,6 @@ Proof.
exists rs'. split. auto.
apply agree_set_mireg_exten with rs; auto.
rewrite (sp_val ms sp rs). auto. auto.
- (* Oundef again *)
- congruence.
(* Ocast8unsigned *)
exists (nextinstr (rs#(ireg_of res) <- (Val.rolm (ms m0) Int.zero (Int.repr 255)))).
split. apply exec_straight_one. repeat (rewrite (ireg_val ms sp rs)); auto. reflexivity.
diff --git a/backend/PPCgenretaddr.v b/backend/PPCgenretaddr.v
new file mode 100644
index 0000000..f2802ec
--- /dev/null
+++ b/backend/PPCgenretaddr.v
@@ -0,0 +1,176 @@
+(** Predictor for return addresses in generated PPC code.
+
+ The [return_address_offset] predicate defined here is used in the
+ concrete semantics for Mach (module [Machconcr]) to determine the
+ return addresses that are stored in activation records. *)
+
+Require Import Coqlib.
+Require Import Maps.
+Require Import AST.
+Require Import Integers.
+Require Import Floats.
+Require Import Values.
+Require Import Mem.
+Require Import Globalenvs.
+Require Import Op.
+Require Import Locations.
+Require Import Mach.
+Require Import PPC.
+Require Import PPCgen.
+
+(** The ``code tail'' of an instruction list [c] is the list of instructions
+ starting at PC [pos]. *)
+
+Inductive code_tail: Z -> code -> code -> Prop :=
+ | code_tail_0: forall c,
+ code_tail 0 c c
+ | code_tail_S: forall pos i c1 c2,
+ code_tail pos c1 c2 ->
+ code_tail (pos + 1) (i :: c1) c2.
+
+Lemma code_tail_pos:
+ forall pos c1 c2, code_tail pos c1 c2 -> pos >= 0.
+Proof.
+ induction 1. omega. omega.
+Qed.
+
+(** Consider a Mach function [f] and a sequence [c] of Mach instructions
+ representing the Mach code that remains to be executed after a
+ function call returns. The predicate [return_address_offset f c ofs]
+ holds if [ofs] is the integer offset of the PPC instruction
+ following the call in the PPC code obtained by translating the
+ code of [f]. Graphically:
+<<
+ Mach function f |--------- Mcall ---------|
+ Mach code c | |--------|
+ | \ \
+ | \ \
+ | \ \
+ PPC code | |--------|
+ PPC function |--------------- Pbl ---------|
+
+ <-------- ofs ------->
+>>
+*)
+
+Inductive return_address_offset: Mach.function -> Mach.code -> int -> Prop :=
+ | return_address_offset_intro:
+ forall c f ofs,
+ code_tail ofs (transl_function f) (transl_code c) ->
+ return_address_offset f c (Int.repr ofs).
+
+(** We now show that such an offset always exists if the Mach code [c]
+ is a suffix of [f.(fn_code)]. This holds because the translation
+ from Mach to PPC is compositional: each Mach instruction becomes
+ zero, one or several PPC instructions, but the order of instructions
+ is preserved. *)
+
+Lemma is_tail_code_tail:
+ forall c1 c2, is_tail c1 c2 -> exists ofs, code_tail ofs c2 c1.
+Proof.
+ induction 1. exists 0; constructor.
+ destruct IHis_tail as [ofs CT]. exists (ofs + 1); constructor; auto.
+Qed.
+
+Hint Resolve is_tail_refl: ppcretaddr.
+
+Ltac IsTail :=
+ auto with ppcretaddr;
+ match goal with
+ | [ |- is_tail _ (_ :: _) ] => constructor; IsTail
+ | [ |- is_tail _ (match ?x with true => _ | false => _ end) ] => destruct x; IsTail
+ | [ |- is_tail _ (match ?x with left _ => _ | right _ => _ end) ] => destruct x; IsTail
+ | [ |- is_tail _ (match ?x with nil => _ | _ :: _ => _ end) ] => destruct x; IsTail
+ | [ |- is_tail _ (match ?x with Tint => _ | Tfloat => _ end) ] => destruct x; IsTail
+ | [ |- is_tail _ (?f _ _ _ _ _ _ ?k) ] => apply is_tail_trans with k; IsTail
+ | [ |- is_tail _ (?f _ _ _ _ _ ?k) ] => apply is_tail_trans with k; IsTail
+ | [ |- is_tail _ (?f _ _ _ _ ?k) ] => apply is_tail_trans with k; IsTail
+ | [ |- is_tail _ (?f _ _ _ ?k) ] => apply is_tail_trans with k; IsTail
+ | [ |- is_tail _ (?f _ _ ?k) ] => apply is_tail_trans with k; IsTail
+ | _ => idtac
+ end.
+
+Lemma loadimm_tail:
+ forall r n k, is_tail k (loadimm r n k).
+Proof. unfold loadimm; intros; IsTail. Qed.
+Hint Resolve loadimm_tail: ppcretaddr.
+
+Lemma addimm_tail:
+ forall r1 r2 n k, is_tail k (addimm r1 r2 n k).
+Proof. unfold addimm, addimm_1, addimm_2; intros; IsTail. Qed.
+Hint Resolve addimm_tail: ppcretaddr.
+
+Lemma andimm_tail:
+ forall r1 r2 n k, is_tail k (andimm r1 r2 n k).
+Proof. unfold andimm; intros; IsTail. Qed.
+Hint Resolve andimm_tail: ppcretaddr.
+
+Lemma orimm_tail:
+ forall r1 r2 n k, is_tail k (orimm r1 r2 n k).
+Proof. unfold orimm; intros; IsTail. Qed.
+Hint Resolve orimm_tail: ppcretaddr.
+
+Lemma xorimm_tail:
+ forall r1 r2 n k, is_tail k (xorimm r1 r2 n k).
+Proof. unfold xorimm; intros; IsTail. Qed.
+Hint Resolve xorimm_tail: ppcretaddr.
+
+Lemma loadind_tail:
+ forall base ofs ty dst k, is_tail k (loadind base ofs ty dst k).
+Proof. unfold loadind; intros; IsTail. Qed.
+Hint Resolve loadind_tail: ppcretaddr.
+
+Lemma storeind_tail:
+ forall src base ofs ty k, is_tail k (storeind src base ofs ty k).
+Proof. unfold storeind; intros; IsTail. Qed.
+Hint Resolve storeind_tail: ppcretaddr.
+
+Lemma floatcomp_tail:
+ forall cmp r1 r2 k, is_tail k (floatcomp cmp r1 r2 k).
+Proof. unfold floatcomp; intros; destruct cmp; IsTail. Qed.
+Hint Resolve floatcomp_tail: ppcretaddr.
+
+Lemma transl_cond_tail:
+ forall cond args k, is_tail k (transl_cond cond args k).
+Proof. unfold transl_cond; intros; destruct cond; IsTail. Qed.
+Hint Resolve transl_cond_tail: ppcretaddr.
+
+Lemma transl_op_tail:
+ forall op args r k, is_tail k (transl_op op args r k).
+Proof. unfold transl_op; intros; destruct op; IsTail. Qed.
+Hint Resolve transl_op_tail: ppcretaddr.
+
+Lemma transl_load_store_tail:
+ forall mk1 mk2 addr args k,
+ is_tail k (transl_load_store mk1 mk2 addr args k).
+Proof. unfold transl_load_store; intros; destruct addr; IsTail. Qed.
+Hint Resolve transl_load_store_tail: ppcretaddr.
+
+Lemma transl_instr_tail:
+ forall i k, is_tail k (transl_instr i k).
+Proof.
+ unfold transl_instr; intros; destruct i; IsTail.
+ destruct m; IsTail.
+ destruct m; IsTail.
+ destruct s0; IsTail.
+ destruct s0; IsTail.
+Qed.
+Hint Resolve transl_instr_tail: ppcretaddr.
+
+Lemma transl_code_tail:
+ forall c1 c2, is_tail c1 c2 -> is_tail (transl_code c1) (transl_code c2).
+Proof.
+ induction 1; simpl. constructor. eapply is_tail_trans; eauto with ppcretaddr.
+Qed.
+
+Lemma return_address_exists:
+ forall f c, is_tail c f.(fn_code) ->
+ exists ra, return_address_offset f c ra.
+Proof.
+ intros. assert (is_tail (transl_code c) (transl_function f)).
+ unfold transl_function. IsTail. apply transl_code_tail; auto.
+ destruct (is_tail_code_tail _ _ H0) as [ofs A].
+ exists (Int.repr ofs). constructor. auto.
+Qed.
+
+
diff --git a/backend/Parallelmove.v b/backend/Parallelmove.v
index b2ec930..3d77b57 100644
--- a/backend/Parallelmove.v
+++ b/backend/Parallelmove.v
@@ -1,3 +1,14 @@
+(** Translation of parallel moves into sequences of individual moves.
+
+ In this file, we adapt the generic "parallel move" algorithm
+ (developed and proved correct in module [Parmov]) to the idiosyncraties
+ of the [LTLin] and [Linear] intermediate languages. While the generic
+ algorithm assumes that registers never overlap, the locations
+ used in [LTLin] and [Linear] can overlap, and assigning one location
+ can set the values of other, overlapping locations to [Vundef].
+ We address this issue in the remainder of this file.
+*)
+
Require Import Coqlib.
Require Parmov.
Require Import Values.
@@ -6,16 +17,28 @@ Require Import AST.
Require Import Locations.
Require Import Conventions.
+(** * Instantiating the generic parallel move algorithm *)
+
+(** The temporary location to use for a move is determined
+ by the type of the data being moved: register [IT2] for an
+ integer datum, and register [FT2] for a floating-point datum. *)
+
Definition temp_for (l: loc) : loc :=
match Loc.type l with Tint => R IT2 | Tfloat => R FT2 end.
Definition parmove (srcs dsts: list loc) :=
- Parmov.parmove2 loc temp_for Loc.eq srcs dsts.
+ Parmov.parmove2 loc Loc.eq temp_for srcs dsts.
Definition moves := (list (loc * loc))%type.
+(** [exec_seq m] gives semantics to a sequence of elementary moves.
+ This semantics ignores the possibility of overlap: only the
+ target locations are updated, but the locations they
+ overlap with are not set to [Vundef]. See [effect_seqmove] below
+ for a semantics that accounts for overlaps. *)
+
Definition exec_seq (m: moves) (e: Locmap.t) : Locmap.t :=
- Parmov.exec_seq loc val Loc.eq m e.
+ Parmov.exec_seq loc Loc.eq val m e.
Lemma temp_for_charact:
forall l, temp_for l = R IT2 \/ temp_for l = R FT2.
@@ -52,6 +75,12 @@ Proof.
apply Loc.notin_not_in; auto. auto.
Qed.
+(** Instantiating the theorems proved in [Parmov], we obtain
+ the following properties of semantic correctness and well-typedness
+ of the generated sequence of moves. Note that the semantic
+ correctness result is stated in terms of the [exec_seq] semantics,
+ and therefore does not account for overlap between locations. *)
+
Lemma parmove_prop_1:
forall srcs dsts,
List.length srcs = List.length dsts ->
@@ -69,8 +98,8 @@ Proof.
intros. apply disjoint_temp_not_temp. apply Loc.disjoint_notin with srcs; auto.
assert (NTD: forall r, In r dsts -> Parmov.is_not_temp loc temp_for r).
intros. apply disjoint_temp_not_temp. apply Loc.disjoint_notin with dsts; auto.
- generalize (Parmov.parmove2_correctness loc temp_for val Loc.eq srcs dsts H NR NTS NTD e).
- change (Parmov.exec_seq loc val Loc.eq (Parmov.parmove2 loc temp_for Loc.eq srcs dsts) e) with e'.
+ generalize (Parmov.parmove2_correctness loc Loc.eq temp_for val srcs dsts H NR NTS NTD e).
+ change (Parmov.exec_seq loc Loc.eq val (Parmov.parmove2 loc Loc.eq temp_for srcs dsts) e) with e'.
intros [A B].
split. auto. intros. apply B. auto. rewrite is_not_temp_charact; auto.
Qed.
@@ -97,7 +126,7 @@ Proof.
tauto.
right. apply temp_for_charact.
intros. apply H.
- apply (Parmov.parmove2_wf_moves loc temp_for Loc.eq srcs dsts s d H0).
+ apply (Parmov.parmove2_wf_moves loc Loc.eq temp_for srcs dsts s d H0).
Qed.
Lemma loc_type_temp_for:
@@ -134,11 +163,21 @@ Proof.
rewrite loc_type_temp_for; auto.
rewrite loc_type_temp_for; auto.
intros. apply H.
- apply (Parmov.parmove2_wf_moves loc temp_for Loc.eq srcs dsts s d H0).
+ apply (Parmov.parmove2_wf_moves loc Loc.eq temp_for srcs dsts s d H0).
Qed.
+(** * Accounting for overlap between locations *)
+
Section EQUIVALENCE.
+(** We now prove the correctness of the generated sequence of elementary
+ moves, accounting for possible overlap between locations.
+ The proof is conducted under the following hypotheses: there must
+ be no partial overlap between
+- two distinct destinations (hypothesis [NOREPET]);
+- a source location and a destination location (hypothesis [NO_OVERLAP]).
+*)
+
Variables srcs dsts: list loc.
Hypothesis LENGTH: List.length srcs = List.length dsts.
Hypothesis NOREPET: Loc.norepet dsts.
@@ -146,9 +185,16 @@ Hypothesis NO_OVERLAP: Loc.no_overlap srcs dsts.
Hypothesis NO_SRCS_TEMP: Loc.disjoint srcs temporaries.
Hypothesis NO_DSTS_TEMP: Loc.disjoint dsts temporaries.
+(** [no_overlap_dests l] holds if location [l] does not partially overlap
+ a destination location: either it is identical to one of the
+ destinations, or it is disjoint from all destinations. *)
+
Definition no_overlap_dests (l: loc) : Prop :=
forall d, In d dsts -> l = d \/ Loc.diff l d.
+(** We show that [no_overlap_dests] holds for any destination location
+ and for any source location. *)
+
Lemma dests_no_overlap_dests:
forall l, In l dsts -> no_overlap_dests l.
Proof.
@@ -201,10 +247,19 @@ Proof.
elim H2; intro; subst d; auto.
Qed.
+(** [locmap_equiv e1 e2] holds if the location maps [e1] and [e2]
+ assign the same values to all locations except temporaries [IT1], [FT1]
+ and except locations that partially overlap a destination. *)
+
Definition locmap_equiv (e1 e2: Locmap.t): Prop :=
forall l,
no_overlap_dests l -> Loc.diff l (R IT1) -> Loc.diff l (R FT1) -> e2 l = e1 l.
+(** The following predicates characterize the effect of one move
+ move ([effect_move]) and of a sequence of elementary moves
+ ([effect_seqmove]). We allow the code generated for one move
+ to use the temporaries [IT1] and [FT1] in any way it needs. *)
+
Definition effect_move (src dst: loc) (e e': Locmap.t): Prop :=
e' dst = e src /\
forall l, Loc.diff l dst -> Loc.diff l (R IT1) -> Loc.diff l (R FT1) -> e' l = e l.
@@ -217,12 +272,18 @@ Inductive effect_seqmove: list (loc * loc) -> Locmap.t -> Locmap.t -> Prop :=
effect_seqmove m e2 e3 ->
effect_seqmove ((s, d) :: m) e1 e3.
+(** The following crucial lemma shows that [locmap_equiv] is preserved
+ by executing one move [d <- s], once using the [effect_move]
+ predicate that accounts for partial overlap and the use of
+ temporaries [IT1], [FT1], or via the [Parmov.update] function that
+ does not account for any of these. *)
+
Lemma effect_move_equiv:
forall s d e1 e2 e1',
(In s srcs \/ s = R IT2 \/ s = R FT2) ->
(In d dsts \/ d = R IT2 \/ d = R FT2) ->
locmap_equiv e1 e2 -> effect_move s d e1 e1' ->
- locmap_equiv e1' (Parmov.update loc val Loc.eq d (e2 s) e2).
+ locmap_equiv e1' (Parmov.update loc Loc.eq val d (e2 s) e2).
Proof.
intros. destruct H2. red; intros.
unfold Parmov.update. destruct (Loc.eq l d).
@@ -231,6 +292,9 @@ Proof.
rewrite H3; auto. apply dest_noteq_diff; auto.
Qed.
+(** We then extend the previous lemma to a sequence [mu] of elementary moves.
+*)
+
Lemma effect_seqmove_equiv:
forall mu e1 e1',
effect_seqmove mu e1 e1' ->
@@ -249,6 +313,13 @@ Proof.
eapply effect_move_equiv; eauto.
Qed.
+(** Here is the main result in this file: executing the sequence
+ of moves returned by the [parmove] function results in the
+ desired state for locations: the final values of destination locations
+ are the initial values of source locations, and all locations
+ that are disjoint from the temporaries and the destinations
+ keep their initial values. *)
+
Lemma effect_parmove:
forall e e',
effect_seqmove (parmove srcs dsts) e e' ->
diff --git a/backend/RTL.v b/backend/RTL.v
index 8b46a7d..7471997 100644
--- a/backend/RTL.v
+++ b/backend/RTL.v
@@ -1,10 +1,9 @@
(** The RTL intermediate language: abstract syntax and semantics.
- RTL (``Register Transfer Language'' is the first intermediate language
- after Cminor.
+ RTL stands for "Register Transfer Language". This is the first
+ intermediate language after Cminor and CminorSel.
*)
-(*Require Import Relations.*)
Require Import Coqlib.
Require Import Maps.
Require Import AST.
@@ -13,6 +12,7 @@ Require Import Values.
Require Import Events.
Require Import Mem.
Require Import Globalenvs.
+Require Import Smallstep.
Require Import Op.
Require Import Registers.
@@ -55,6 +55,7 @@ Inductive instruction: Set :=
function name), giving it the values of registers [args]
as arguments. It stores the return value in [dest] and branches
to [succ]. *)
+ | Itailcall: signature -> reg + ident -> list reg -> instruction
| Ialloc: reg -> reg -> node -> instruction
(** [Ialloc arg dest succ] allocates a fresh block of size
the contents of register [arg], stores a pointer to this
@@ -111,6 +112,52 @@ Fixpoint init_regs (vl: list val) (rl: list reg) {struct rl} : regset :=
| _, _ => Regmap.init Vundef
end.
+Inductive stackframe : Set :=
+ | Stackframe:
+ forall (res: reg) (c: code) (sp: val) (pc: node) (rs: regset),
+ stackframe.
+
+Inductive state : Set :=
+ | State:
+ forall (stack: list stackframe) (c: code) (sp: val) (pc: node)
+ (rs: regset) (m: mem), state
+ | Callstate:
+ forall (stack: list stackframe) (f: fundef) (args: list val) (m: mem),
+ state
+ | Returnstate:
+ forall (stack: list stackframe) (v: val) (m: mem),
+ state.
+
+(** The dynamic semantics of RTL is given in small-step style, as a
+ set of transitions between states. A state captures the current
+ point in the execution. Three kinds of states appear in the transitions:
+
+- [State cs c sp pc rs m] describes an execution point within a function.
+ [c] is the code for the current function (a CFG).
+ [sp] is the pointer to the stack block for its current activation
+ (as in Cminor).
+ [pc] is the current program point (CFG node) within the code [c].
+ [rs] gives the current values for the pseudo-registers.
+ [m] is the current memory state.
+- [Callstate cs f args m] is an intermediate state that appears during
+ function calls.
+ [f] is the function definition that we are calling.
+ [args] (a list of values) are the arguments for this call.
+ [m] is the current memory state.
+- [Returnstate cs v m] is an intermediate state that appears when a
+ function terminates and returns to its caller.
+ [v] is the return value and [m] the current memory state.
+
+In all three kinds of states, the [cs] parameter represents the call stack.
+It is a list of frames [Stackframe res c sp pc rs]. Each frame represents
+a function call in progress.
+[res] is the pseudo-register that will receive the result of the call.
+[c] is the code of the calling function.
+[sp] is its stack pointer.
+[pc] is the program point for the instruction that follows the call.
+[rs] is the state of registers in the calling function.
+*)
+
Section RELSEM.
Variable ge: genv.
@@ -126,194 +173,142 @@ Definition find_function
end
end.
-(** The dynamic semantics of RTL is a combination of small-step (transition)
- semantics and big-step semantics. Execution of an instruction performs
- a single transition to the next instruction (small-step), except if
- the instruction is a function call. In this case, the whole body of
- the called function is executed at once and the transition terminates
- on the instruction immediately following the call in the caller function.
- Such ``mixed-step'' semantics is convenient for reasoning over
- intra-procedural analyses and transformations. It also dispenses us
- from making the call stack explicit in the semantics.
-
- The semantics is organized in three mutually inductive predicates.
- The first is [exec_instr ge c sp pc rs m pc' rs' m']. [ge] is the
- global environment (see module [Genv]), [c] the CFG for the current
- function, and [sp] the pointer to the stack block for its
- current activation (as in Cminor). [pc], [rs] and [m] is the
- initial state of the transition: program point (CFG node) [pc],
- register state (mapping of pseudo-registers to values) [rs],
- and memory state [m]. The final state is [pc'], [rs'] and [m']. *)
-
-Inductive exec_instr: code -> val ->
- node -> regset -> mem -> trace ->
- node -> regset -> mem -> Prop :=
+(** The transitions are presented as an inductive predicate
+ [step ge st1 t st2], where [ge] is the global environment,
+ [st1] the initial state, [st2] the final state, and [t] the trace
+ of system calls performed during this transition. *)
+
+Inductive step: state -> trace -> state -> Prop :=
| exec_Inop:
- forall c sp pc rs m pc',
+ forall s c sp pc rs m pc',
c!pc = Some(Inop pc') ->
- exec_instr c sp pc rs m E0 pc' rs m
+ step (State s c sp pc rs m)
+ E0 (State s c sp pc' rs m)
| exec_Iop:
- forall c sp pc rs m op args res pc' v,
+ forall s c sp pc rs m op args res pc' v,
c!pc = Some(Iop op args res pc') ->
- eval_operation ge sp op rs##args = Some v ->
- exec_instr c sp pc rs m E0 pc' (rs#res <- v) m
+ eval_operation ge sp op rs##args m = Some v ->
+ step (State s c sp pc rs m)
+ E0 (State s c sp pc' (rs#res <- v) m)
| exec_Iload:
- forall c sp pc rs m chunk addr args dst pc' a v,
+ forall s c sp pc rs m chunk addr args dst pc' a v,
c!pc = Some(Iload chunk addr args dst pc') ->
eval_addressing ge sp addr rs##args = Some a ->
Mem.loadv chunk m a = Some v ->
- exec_instr c sp pc rs m E0 pc' (rs#dst <- v) m
+ step (State s c sp pc rs m)
+ E0 (State s c sp pc' (rs#dst <- v) m)
| exec_Istore:
- forall c sp pc rs m chunk addr args src pc' a m',
+ forall s c sp pc rs m chunk addr args src pc' a m',
c!pc = Some(Istore chunk addr args src pc') ->
eval_addressing ge sp addr rs##args = Some a ->
Mem.storev chunk m a rs#src = Some m' ->
- exec_instr c sp pc rs m E0 pc' rs m'
+ step (State s c sp pc rs m)
+ E0 (State s c sp pc' rs m')
| exec_Icall:
- forall c sp pc rs m sig ros args res pc' f vres m' t,
+ forall s c sp pc rs m sig ros args res pc' f,
c!pc = Some(Icall sig ros args res pc') ->
find_function ros rs = Some f ->
funsig f = sig ->
- exec_function f rs##args m t vres m' ->
- exec_instr c sp pc rs m t pc' (rs#res <- vres) m'
+ step (State s c sp pc rs m)
+ E0 (Callstate (Stackframe res c sp pc' rs :: s) f rs##args m)
+ | exec_Itailcall:
+ forall s c stk pc rs m sig ros args f,
+ c!pc = Some(Itailcall sig ros args) ->
+ find_function ros rs = Some f ->
+ funsig f = sig ->
+ step (State s c (Vptr stk Int.zero) pc rs m)
+ E0 (Callstate s f rs##args (Mem.free m stk))
| exec_Ialloc:
- forall c sp pc rs m pc' arg res sz m' b,
+ forall s c sp pc rs m pc' arg res sz m' b,
c!pc = Some(Ialloc arg res pc') ->
rs#arg = Vint sz ->
Mem.alloc m 0 (Int.signed sz) = (m', b) ->
- exec_instr c sp pc rs m E0 pc' (rs#res <- (Vptr b Int.zero)) m'
+ step (State s c sp pc rs m)
+ E0 (State s c sp pc' (rs#res <- (Vptr b Int.zero)) m')
| exec_Icond_true:
- forall c sp pc rs m cond args ifso ifnot,
+ forall s c sp pc rs m cond args ifso ifnot,
c!pc = Some(Icond cond args ifso ifnot) ->
- eval_condition cond rs##args = Some true ->
- exec_instr c sp pc rs m E0 ifso rs m
+ eval_condition cond rs##args m = Some true ->
+ step (State s c sp pc rs m)
+ E0 (State s c sp ifso rs m)
| exec_Icond_false:
- forall c sp pc rs m cond args ifso ifnot,
+ forall s c sp pc rs m cond args ifso ifnot,
c!pc = Some(Icond cond args ifso ifnot) ->
- eval_condition cond rs##args = Some false ->
- exec_instr c sp pc rs m E0 ifnot rs m
-
-(** [exec_instrs ge c sp pc rs m pc' rs' m'] is the reflexive
- transitive closure of [exec_instr]. It corresponds to the execution
- of zero, one or finitely many transitions. *)
-
-with exec_instrs: code -> val ->
- node -> regset -> mem -> trace ->
- node -> regset -> mem -> Prop :=
- | exec_refl:
- forall c sp pc rs m,
- exec_instrs c sp pc rs m E0 pc rs m
- | exec_one:
- forall c sp pc rs m t pc' rs' m',
- exec_instr c sp pc rs m t pc' rs' m' ->
- exec_instrs c sp pc rs m t pc' rs' m'
- | exec_trans:
- forall c sp pc1 rs1 m1 t1 pc2 rs2 m2 t2 pc3 rs3 m3 t3,
- exec_instrs c sp pc1 rs1 m1 t1 pc2 rs2 m2 ->
- exec_instrs c sp pc2 rs2 m2 t2 pc3 rs3 m3 ->
- t3 = t1 ** t2 ->
- exec_instrs c sp pc1 rs1 m1 t3 pc3 rs3 m3
-
-(** [exec_function ge f args m res m'] executes a function application.
- [f] is the called function, [args] the values of its arguments,
- and [m] the memory state at the beginning of the call. [res] is
- the returned value: the value of [r] if the function terminates with
- a [Ireturn (Some r)], or [Vundef] if it terminates with [Ireturn None].
- Evaluation proceeds by executing transitions from the function's entry
- point to the first [Ireturn] instruction encountered. It is preceeded
- by the allocation of the stack activation block and the binding
- of register parameters to the provided arguments.
- (Non-parameter registers are initialized to [Vundef].) Before returning,
- the stack activation block is freed. *)
-
-with exec_function: fundef -> list val -> mem -> trace ->
- val -> mem -> Prop :=
- | exec_funct_internal:
- forall f m m1 stk args t pc rs m2 or vres,
- Mem.alloc m 0 f.(fn_stacksize) = (m1, stk) ->
- exec_instrs f.(fn_code) (Vptr stk Int.zero)
- f.(fn_entrypoint) (init_regs args f.(fn_params)) m1
- t pc rs m2 ->
- f.(fn_code)!pc = Some(Ireturn or) ->
- vres = regmap_optget or Vundef rs ->
- exec_function (Internal f) args m t vres (Mem.free m2 stk)
- | exec_funct_external:
- forall ef args m t res,
+ eval_condition cond rs##args m = Some false ->
+ step (State s c sp pc rs m)
+ E0 (State s c sp ifnot rs m)
+ | exec_Ireturn:
+ forall s c stk pc rs m or,
+ c!pc = Some(Ireturn or) ->
+ step (State s c (Vptr stk Int.zero) pc rs m)
+ E0 (Returnstate s (regmap_optget or Vundef rs) (Mem.free m stk))
+ | exec_function_internal:
+ forall s f args m m' stk,
+ Mem.alloc m 0 f.(fn_stacksize) = (m', stk) ->
+ step (Callstate s (Internal f) args m)
+ E0 (State s
+ f.(fn_code)
+ (Vptr stk Int.zero)
+ f.(fn_entrypoint)
+ (init_regs args f.(fn_params))
+ m')
+ | exec_function_external:
+ forall s ef args res t m,
event_match ef args t res ->
- exec_function (External ef) args m t res m.
-
-Scheme exec_instr_ind_3 := Minimality for exec_instr Sort Prop
- with exec_instrs_ind_3 := Minimality for exec_instrs Sort Prop
- with exec_function_ind_3 := Minimality for exec_function Sort Prop.
-
-(** Some derived execution rules. *)
-
-Lemma exec_step:
- forall c sp pc1 rs1 m1 t1 pc2 rs2 m2 t2 pc3 rs3 m3 t3,
- exec_instr c sp pc1 rs1 m1 t1 pc2 rs2 m2 ->
- exec_instrs c sp pc2 rs2 m2 t2 pc3 rs3 m3 ->
- t3 = t1 ** t2 ->
- exec_instrs c sp pc1 rs1 m1 t3 pc3 rs3 m3.
-Proof.
- intros. eapply exec_trans. apply exec_one. eauto. eauto. auto.
-Qed.
+ step (Callstate s (External ef) args m)
+ t (Returnstate s res m)
+ | exec_return:
+ forall res c sp pc rs s vres m,
+ step (Returnstate (Stackframe res c sp pc rs :: s) vres m)
+ E0 (State s c sp pc (rs#res <- vres) m).
Lemma exec_Iop':
- forall c sp pc rs m op args res pc' rs' v,
+ forall s c sp pc rs m op args res pc' rs' v,
c!pc = Some(Iop op args res pc') ->
- eval_operation ge sp op rs##args = Some v ->
+ eval_operation ge sp op rs##args m = Some v ->
rs' = (rs#res <- v) ->
- exec_instr c sp pc rs m E0 pc' rs' m.
+ step (State s c sp pc rs m)
+ E0 (State s c sp pc' rs' m).
Proof.
intros. subst rs'. eapply exec_Iop; eauto.
Qed.
Lemma exec_Iload':
- forall c sp pc rs m chunk addr args dst pc' rs' a v,
+ forall s c sp pc rs m chunk addr args dst pc' rs' a v,
c!pc = Some(Iload chunk addr args dst pc') ->
eval_addressing ge sp addr rs##args = Some a ->
Mem.loadv chunk m a = Some v ->
rs' = (rs#dst <- v) ->
- exec_instr c sp pc rs m E0 pc' rs' m.
+ step (State s c sp pc rs m)
+ E0 (State s c sp pc' rs' m).
Proof.
intros. subst rs'. eapply exec_Iload; eauto.
Qed.
-(** If a transition can take place from [pc], the instruction at [pc]
- is defined in the CFG. *)
+End RELSEM.
-Lemma exec_instr_present:
- forall c sp pc rs m t pc' rs' m',
- exec_instr c sp pc rs m t pc' rs' m' ->
- c!pc <> None.
-Proof.
- induction 1; congruence.
-Qed.
+(** Execution of whole programs are described as sequences of transitions
+ from an initial state to a final state. An initial state is a [Callstate]
+ corresponding to the invocation of the ``main'' function of the program
+ without arguments and with an empty call stack. *)
-Lemma exec_instrs_present:
- forall c sp pc rs m t pc' rs' m',
- exec_instrs c sp pc rs m t pc' rs' m' ->
- c!pc' <> None -> c!pc <> None.
-Proof.
- induction 1; intros.
- auto.
- eapply exec_instr_present; eauto.
- eauto.
-Qed.
+Inductive initial_state (p: program): state -> Prop :=
+ | initial_state_intro: forall b f,
+ let ge := Genv.globalenv p in
+ let m0 := Genv.init_mem p in
+ Genv.find_symbol ge p.(prog_main) = Some b ->
+ Genv.find_funct_ptr ge b = Some f ->
+ funsig f = mksignature nil (Some Tint) ->
+ initial_state p (Callstate nil f nil m0).
-End RELSEM.
+(** A final state is a [Returnstate] with an empty call stack. *)
-(** Execution of whole programs. As in Cminor, we call the ``main'' function
- with no arguments and observe its return value. *)
+Inductive final_state: state -> int -> Prop :=
+ | final_state_intro: forall r m,
+ final_state (Returnstate nil (Vint r) m) r.
-Definition exec_program (p: program) (t: trace) (r: val) : Prop :=
- let ge := Genv.globalenv p in
- let m0 := Genv.init_mem p in
- exists b, exists f, exists m,
- Genv.find_symbol ge p.(prog_main) = Some b /\
- Genv.find_funct_ptr ge b = Some f /\
- funsig f = mksignature nil (Some Tint) /\
- exec_function ge f nil m0 t r m.
+Definition exec_program (p: program) (beh: program_behavior) : Prop :=
+ program_behaves step (initial_state p) final_state (Genv.globalenv p) beh.
(** * Operations on RTL abstract syntax *)
@@ -330,21 +325,13 @@ Definition successors (f: function) (pc: node) : list node :=
| Iload chunk addr args dst s => s :: nil
| Istore chunk addr args src s => s :: nil
| Icall sig ros args res s => s :: nil
+ | Itailcall sig ros args => nil
| Ialloc arg res s => s :: nil
| Icond cond args ifso ifnot => ifso :: ifnot :: nil
| Ireturn optarg => nil
end
end.
-Lemma successors_correct:
- forall ge f sp pc rs m t pc' rs' m',
- exec_instr ge f.(fn_code) sp pc rs m t pc' rs' m' ->
- In pc' (successors f pc).
-Proof.
- intros ge f. unfold successors. generalize (fn_code f).
- induction 1; rewrite H; simpl; tauto.
-Qed.
-
(** Transformation of a RTL function instruction by instruction.
This applies a given transformation function to all instructions
of a function and constructs a transformed function from that. *)
diff --git a/backend/RTLbigstep.v b/backend/RTLbigstep.v
new file mode 100644
index 0000000..0ad6e68
--- /dev/null
+++ b/backend/RTLbigstep.v
@@ -0,0 +1,400 @@
+(** An alternate, mixed-step semantics for the RTL intermediate language. *)
+
+Require Import Coqlib.
+Require Import Maps.
+Require Import AST.
+Require Import Integers.
+Require Import Values.
+Require Import Events.
+Require Import Mem.
+Require Import Globalenvs.
+Require Import Smallstep.
+Require Import Op.
+Require Import Registers.
+Require Import RTL.
+
+Section BIGSTEP.
+
+Variable ge: genv.
+
+(** The dynamic semantics of RTL is a combination of small-step (transition)
+ semantics and big-step semantics. Execution of an instruction performs
+ a single transition to the next instruction (small-step), except if
+ the instruction is a function call. In this case, the whole body of
+ the called function is executed at once and the transition terminates
+ on the instruction immediately following the call in the caller function.
+ Such ``mixed-step'' semantics is convenient for reasoning over
+ intra-procedural analyses and transformations. It also dispenses us
+ from making the call stack explicit in the semantics.
+
+ The semantics is organized in three mutually inductive predicates.
+ The first is [exec_instr ge c sp pc rs m pc' rs' m']. [ge] is the
+ global environment (see module [Genv]), [c] the CFG for the current
+ function, and [sp] the pointer to the stack block for its
+ current activation (as in Cminor). [pc], [rs] and [m] is the
+ initial state of the transition: program point (CFG node) [pc],
+ register state (mapping of pseudo-registers to values) [rs],
+ and memory state [m]. The final state is [pc'], [rs'] and [m']. *)
+
+Inductive exec_instr: code -> val ->
+ node -> regset -> mem -> trace ->
+ node -> regset -> mem -> Prop :=
+ | exec_Inop:
+ forall c sp pc rs m pc',
+ c!pc = Some(Inop pc') ->
+ exec_instr c sp pc rs m E0 pc' rs m
+ | exec_Iop:
+ forall c sp pc rs m op args res pc' v,
+ c!pc = Some(Iop op args res pc') ->
+ eval_operation ge sp op rs##args m = Some v ->
+ exec_instr c sp pc rs m E0 pc' (rs#res <- v) m
+ | exec_Iload:
+ forall c sp pc rs m chunk addr args dst pc' a v,
+ c!pc = Some(Iload chunk addr args dst pc') ->
+ eval_addressing ge sp addr rs##args = Some a ->
+ Mem.loadv chunk m a = Some v ->
+ exec_instr c sp pc rs m E0 pc' (rs#dst <- v) m
+ | exec_Istore:
+ forall c sp pc rs m chunk addr args src pc' a m',
+ c!pc = Some(Istore chunk addr args src pc') ->
+ eval_addressing ge sp addr rs##args = Some a ->
+ Mem.storev chunk m a rs#src = Some m' ->
+ exec_instr c sp pc rs m E0 pc' rs m'
+ | exec_Icall:
+ forall c sp pc rs m sig ros args res pc' f vres m' t,
+ c!pc = Some(Icall sig ros args res pc') ->
+ find_function ge ros rs = Some f ->
+ funsig f = sig ->
+ exec_function f rs##args m t vres m' ->
+ exec_instr c sp pc rs m t pc' (rs#res <- vres) m'
+ | exec_Ialloc:
+ forall c sp pc rs m pc' arg res sz m' b,
+ c!pc = Some(Ialloc arg res pc') ->
+ rs#arg = Vint sz ->
+ Mem.alloc m 0 (Int.signed sz) = (m', b) ->
+ exec_instr c sp pc rs m E0 pc' (rs#res <- (Vptr b Int.zero)) m'
+ | exec_Icond_true:
+ forall c sp pc rs m cond args ifso ifnot,
+ c!pc = Some(Icond cond args ifso ifnot) ->
+ eval_condition cond rs##args m = Some true ->
+ exec_instr c sp pc rs m E0 ifso rs m
+ | exec_Icond_false:
+ forall c sp pc rs m cond args ifso ifnot,
+ c!pc = Some(Icond cond args ifso ifnot) ->
+ eval_condition cond rs##args m = Some false ->
+ exec_instr c sp pc rs m E0 ifnot rs m
+
+(** [exec_body ge c sp pc rs m res m'] repeatedly executes
+ instructions starting at [pc] in [c], until it
+ reaches a return or tailcall instruction. It performs
+ that instruction and sets [res] to the return value
+ and [m'] to the final memory state. *)
+
+with exec_body: code -> val ->
+ node -> regset -> mem -> trace ->
+ val -> mem -> Prop :=
+ | exec_body_step: forall c sp pc rs m t1 pc1 rs1 m1 t2 t res m2,
+ exec_instr c sp pc rs m t1 pc1 rs1 m1 ->
+ exec_body c sp pc1 rs1 m1 t2 res m2 ->
+ t = t1 ** t2 ->
+ exec_body c sp pc rs m t res m2
+ | exec_Ireturn: forall c stk pc rs m or res,
+ c!pc = Some(Ireturn or) ->
+ res = regmap_optget or Vundef rs ->
+ exec_body c (Vptr stk Int.zero) pc rs m E0 res (Mem.free m stk)
+ | exec_Itailcall: forall c stk pc rs m sig ros args f t res m',
+ c!pc = Some(Itailcall sig ros args) ->
+ find_function ge ros rs = Some f ->
+ funsig f = sig ->
+ exec_function f rs##args (Mem.free m stk) t res m' ->
+ exec_body c (Vptr stk Int.zero) pc rs m t res m'
+
+(** [exec_function ge f args m res m'] executes a function application.
+ [f] is the called function, [args] the values of its arguments,
+ and [m] the memory state at the beginning of the call. [res] is
+ the returned value: the value of [r] if the function terminates with
+ a [Ireturn (Some r)], or [Vundef] if it terminates with [Ireturn None].
+ Evaluation proceeds by executing transitions from the function's entry
+ point to the first [Ireturn] instruction encountered. It is preceeded
+ by the allocation of the stack activation block and the binding
+ of register parameters to the provided arguments.
+ (Non-parameter registers are initialized to [Vundef].) Before returning,
+ the stack activation block is freed. *)
+
+with exec_function: fundef -> list val -> mem -> trace ->
+ val -> mem -> Prop :=
+ | exec_funct_internal:
+ forall f m m1 stk args t m2 vres,
+ Mem.alloc m 0 f.(fn_stacksize) = (m1, stk) ->
+ exec_body f.(fn_code) (Vptr stk Int.zero)
+ f.(fn_entrypoint) (init_regs args f.(fn_params)) m1
+ t vres m2 ->
+ exec_function (Internal f) args m t vres m2
+ | exec_funct_external:
+ forall ef args m t res,
+ event_match ef args t res ->
+ exec_function (External ef) args m t res m.
+
+Scheme exec_instr_ind_3 := Minimality for exec_instr Sort Prop
+ with exec_body_ind_3 := Minimality for exec_body Sort Prop
+ with exec_function_ind_3 := Minimality for exec_function Sort Prop.
+
+(** The reflexive transitive closure of [exec_instr]. *)
+
+Inductive exec_instrs: code -> val ->
+ node -> regset -> mem -> trace ->
+ node -> regset -> mem -> Prop :=
+ | exec_refl:
+ forall c sp pc rs m,
+ exec_instrs c sp pc rs m E0 pc rs m
+ | exec_one:
+ forall c sp pc rs m t pc' rs' m',
+ exec_instr c sp pc rs m t pc' rs' m' ->
+ exec_instrs c sp pc rs m t pc' rs' m'
+ | exec_trans:
+ forall c sp pc1 rs1 m1 t1 pc2 rs2 m2 t2 pc3 rs3 m3 t3,
+ exec_instrs c sp pc1 rs1 m1 t1 pc2 rs2 m2 ->
+ exec_instrs c sp pc2 rs2 m2 t2 pc3 rs3 m3 ->
+ t3 = t1 ** t2 ->
+ exec_instrs c sp pc1 rs1 m1 t3 pc3 rs3 m3.
+
+(** Some derived execution rules. *)
+
+Lemma exec_instrs_exec_body:
+ forall c sp pc1 rs1 m1 t1 pc2 rs2 m2,
+ exec_instrs c sp pc1 rs1 m1 t1 pc2 rs2 m2 ->
+ forall res t2 m3 t3,
+ exec_body c sp pc2 rs2 m2 t2 res m3 ->
+ t3 = t1 ** t2 ->
+ exec_body c sp pc1 rs1 m1 t3 res m3.
+Proof.
+ induction 1; intros.
+ subst t3. rewrite E0_left. auto.
+ eapply exec_body_step; eauto.
+ eapply IHexec_instrs1. eapply IHexec_instrs2. eauto.
+ eauto. traceEq.
+Qed.
+
+Lemma exec_step:
+ forall c sp pc1 rs1 m1 t1 pc2 rs2 m2 t2 pc3 rs3 m3 t3,
+ exec_instr c sp pc1 rs1 m1 t1 pc2 rs2 m2 ->
+ exec_instrs c sp pc2 rs2 m2 t2 pc3 rs3 m3 ->
+ t3 = t1 ** t2 ->
+ exec_instrs c sp pc1 rs1 m1 t3 pc3 rs3 m3.
+Proof.
+ intros. eapply exec_trans. apply exec_one. eauto. eauto. auto.
+Qed.
+
+Lemma exec_Iop':
+ forall c sp pc rs m op args res pc' rs' v,
+ c!pc = Some(Iop op args res pc') ->
+ eval_operation ge sp op rs##args m = Some v ->
+ rs' = (rs#res <- v) ->
+ exec_instr c sp pc rs m E0 pc' rs' m.
+Proof.
+ intros. subst rs'. eapply exec_Iop; eauto.
+Qed.
+
+Lemma exec_Iload':
+ forall c sp pc rs m chunk addr args dst pc' rs' a v,
+ c!pc = Some(Iload chunk addr args dst pc') ->
+ eval_addressing ge sp addr rs##args = Some a ->
+ Mem.loadv chunk m a = Some v ->
+ rs' = (rs#dst <- v) ->
+ exec_instr c sp pc rs m E0 pc' rs' m.
+Proof.
+ intros. subst rs'. eapply exec_Iload; eauto.
+Qed.
+
+(** Experimental: coinductive big-step semantics for divergence. *)
+
+CoInductive diverge_body:
+ code -> val -> node -> regset -> mem -> traceinf -> Prop :=
+ | diverge_step: forall c sp pc rs m t1 pc1 rs1 m1 T2 T,
+ exec_instr c sp pc rs m t1 pc1 rs1 m1 ->
+ diverge_body c sp pc1 rs1 m1 T2 ->
+ T = t1 *** T2 ->
+ diverge_body c sp pc rs m T
+ | diverge_Icall:
+ forall c sp pc rs m sig ros args res pc' f T,
+ c!pc = Some(Icall sig ros args res pc') ->
+ find_function ge ros rs = Some f ->
+ funsig f = sig ->
+ diverge_function f rs##args m T ->
+ diverge_body c sp pc rs m T
+ | diverge_Itailcall: forall c stk pc rs m sig ros args f T,
+ c!pc = Some(Itailcall sig ros args) ->
+ find_function ge ros rs = Some f ->
+ funsig f = sig ->
+ diverge_function f rs##args (Mem.free m stk) T ->
+ diverge_body c (Vptr stk Int.zero) pc rs m T
+
+with diverge_function: fundef -> list val -> mem -> traceinf -> Prop :=
+ | diverge_funct_internal:
+ forall f m m1 stk args T,
+ Mem.alloc m 0 f.(fn_stacksize) = (m1, stk) ->
+ diverge_body f.(fn_code) (Vptr stk Int.zero)
+ f.(fn_entrypoint) (init_regs args f.(fn_params)) m1
+ T ->
+ diverge_function (Internal f) args m T.
+
+End BIGSTEP.
+
+(** Execution of whole programs. *)
+
+Inductive exec_program (p: program): program_behavior -> Prop :=
+ | exec_program_terminates: forall b f t r m,
+ let ge := Genv.globalenv p in
+ let m0 := Genv.init_mem p in
+ Genv.find_symbol ge p.(prog_main) = Some b ->
+ Genv.find_funct_ptr ge b = Some f ->
+ funsig f = mksignature nil (Some Tint) ->
+ exec_function ge f nil m0 t (Vint r) m ->
+ exec_program p (Terminates t r)
+ | exec_program_diverges: forall b f T,
+ let ge := Genv.globalenv p in
+ let m0 := Genv.init_mem p in
+ Genv.find_symbol ge p.(prog_main) = Some b ->
+ Genv.find_funct_ptr ge b = Some f ->
+ funsig f = mksignature nil (Some Tint) ->
+ diverge_function ge f nil m0 T ->
+ exec_program p (Diverges T).
+
+(** * Equivalence with the transition semantics. *)
+
+Section EQUIVALENCE.
+
+Variable ge: genv.
+
+Definition exec_instr_prop
+ (c: code) (sp: val) (pc1: node) (rs1: regset) (m1: mem)
+ (t: trace) (pc2: node) (rs2: regset) (m2: mem) : Prop :=
+ forall s,
+ plus step ge (State s c sp pc1 rs1 m1)
+ t (State s c sp pc2 rs2 m2).
+
+Definition exec_body_prop
+ (c: code) (sp: val) (pc1: node) (rs1: regset) (m1: mem)
+ (t: trace) (res: val) (m2: mem) : Prop :=
+ forall s,
+ plus step ge (State s c sp pc1 rs1 m1)
+ t (Returnstate s res m2).
+
+Definition exec_function_prop
+ (f: fundef) (args: list val) (m1: mem)
+ (t: trace) (res: val) (m2: mem) : Prop :=
+ forall s,
+ plus step ge (Callstate s f args m1)
+ t (Returnstate s res m2).
+
+Lemma exec_steps:
+ (forall c sp pc1 rs1 m1 t pc2 rs2 m2,
+ exec_instr ge c sp pc1 rs1 m1 t pc2 rs2 m2 ->
+ exec_instr_prop c sp pc1 rs1 m1 t pc2 rs2 m2) /\
+ (forall c sp pc1 rs1 m1 t res m2,
+ exec_body ge c sp pc1 rs1 m1 t res m2 ->
+ exec_body_prop c sp pc1 rs1 m1 t res m2) /\
+ (forall f args m1 t res m2,
+ exec_function ge f args m1 t res m2 ->
+ exec_function_prop f args m1 t res m2).
+Proof.
+ set (IND := fun a b c d e f g h i j k l m =>
+ conj (exec_instr_ind_3 ge exec_instr_prop exec_body_prop exec_function_prop a b c d e f g h i j k l m)
+ (conj (exec_body_ind_3 ge exec_instr_prop exec_body_prop exec_function_prop a b c d e f g h i j k l m)
+ (exec_function_ind_3 ge exec_instr_prop exec_body_prop exec_function_prop a b c d e f g h i j k l m))).
+ apply IND; clear IND;
+ intros; red; intros.
+ (* nop *)
+ apply plus_one. eapply RTL.exec_Inop; eauto.
+ (* op *)
+ apply plus_one. eapply RTL.exec_Iop'; eauto.
+ (* load *)
+ apply plus_one. eapply RTL.exec_Iload'; eauto.
+ (* store *)
+ apply plus_one. eapply RTL.exec_Istore; eauto.
+ (* call *)
+ eapply plus_left'. eapply RTL.exec_Icall; eauto.
+ eapply plus_right'. apply H3. apply RTL.exec_return.
+ eauto. traceEq.
+ (* alloc *)
+ apply plus_one. eapply RTL.exec_Ialloc; eauto.
+ (* cond true *)
+ apply plus_one. eapply RTL.exec_Icond_true; eauto.
+ (* cond false *)
+ apply plus_one. eapply RTL.exec_Icond_false; eauto.
+ (* body step *)
+ eapply plus_trans. apply H0. apply H2. auto.
+ (* body return *)
+ apply plus_one. rewrite H0. eapply RTL.exec_Ireturn; eauto.
+ (* body tailcall *)
+ eapply plus_left'. eapply RTL.exec_Itailcall; eauto.
+ apply H3. traceEq.
+ (* internal function *)
+ eapply plus_left'. eapply RTL.exec_function_internal; eauto.
+ apply H1. traceEq.
+ (* external function *)
+ apply plus_one. eapply RTL.exec_function_external; eauto.
+Qed.
+
+Lemma diverge_function_steps:
+ forall fd args m T s,
+ diverge_function ge fd args m T ->
+ forever step ge (Callstate s fd args m) T.
+Proof.
+ assert (diverge_function_steps':
+ forall fd args m T s,
+ diverge_function ge fd args m T ->
+ forever_N step ge O (Callstate s fd args m) T).
+ cofix COINDHYP1.
+ assert (diverge_body_steps: forall c sp pc rs m T s,
+ diverge_body ge c sp pc rs m T ->
+ forever_N step ge O (State s c sp pc rs m) T).
+ cofix COINDHYP2; intros.
+ inv H.
+ (* step *)
+ apply forever_N_plus with (State s c sp pc1 rs1 m1) O.
+ destruct exec_steps as [E [F G]].
+ apply E. assumption.
+ apply COINDHYP2. assumption.
+ (* call *)
+ change T with (E0 *** T).
+ apply forever_N_plus with (Callstate (Stackframe res c sp pc' rs :: s)
+ f rs##args m) O.
+ apply plus_one. eapply RTL.exec_Icall; eauto.
+ apply COINDHYP1. assumption.
+ (* tailcall *)
+ change T with (E0 *** T).
+ apply forever_N_plus with (Callstate s f rs##args (free m stk)) O.
+ apply plus_one. eapply RTL.exec_Itailcall; eauto.
+ apply COINDHYP1. assumption.
+ (* internal function *)
+ intros. inv H.
+ change T with (E0 *** T).
+ apply forever_N_plus with
+ (State s f.(fn_code) (Vptr stk Int.zero)
+ f.(fn_entrypoint) (init_regs args f.(fn_params)) m1) O.
+ apply plus_one. eapply RTL.exec_function_internal; eauto.
+ apply diverge_body_steps. assumption.
+ (* conclusion *)
+ intros. eapply forever_N_forever. eauto.
+Qed.
+
+End EQUIVALENCE.
+
+Theorem exec_program_bigstep_smallstep:
+ forall p beh,
+ exec_program p beh ->
+ RTL.exec_program p beh.
+Proof.
+ intros. unfold RTL.exec_program. inv H.
+ econstructor.
+ econstructor; eauto.
+ apply plus_star.
+ destruct (exec_steps (Genv.globalenv p)) as [E [F G]].
+ apply (G _ _ _ _ _ _ H3).
+ constructor.
+ econstructor.
+ econstructor; eauto.
+ apply diverge_function_steps. auto.
+Qed.
+
diff --git a/backend/RTLgen.v b/backend/RTLgen.v
index b38964d..117631e 100644
--- a/backend/RTLgen.v
+++ b/backend/RTLgen.v
@@ -1,21 +1,25 @@
-(** Translation from Cminor to RTL. *)
+(** Translation from CminorSel to RTL. *)
Require Import Coqlib.
+Require Errors.
Require Import Maps.
Require Import AST.
Require Import Integers.
Require Import Values.
+Require Import Switch.
Require Import Op.
Require Import Registers.
-Require Import Cminor.
+Require Import CminorSel.
Require Import RTL.
+Open Local Scope string_scope.
+
(** * Translation environments and state *)
(** The translation functions are parameterized by the following
- compile-time environment, which maps Cminor local variables and
+ compile-time environment, which maps CminorSel local variables and
let-bound variables to RTL registers. The mapping for local variables
- is computed from the Cminor variable declarations at the beginning of
+ is computed from the CminorSel variable declarations at the beginning of
the translation of a function, and does not change afterwards.
The mapping for let-bound variables is initially empty and updated
during translation of expressions, when crossing a [Elet] binding. *)
@@ -46,9 +50,10 @@ Record state: Set := mkstate {
to modify the global state. These luxuries are not available in Coq,
however. Instead, we use a monadic encoding of the translation:
translation functions take the current global state as argument,
- and return either [Error] to denote an error, or [OK r s] to denote
+ and return either [Error msg] to denote an error, or [OK r s] to denote
success. [s] is the modified state, and [r] the result value of the
- translation function.
+ translation function. In the error case, [msg] is an error message
+ (see modules [Errors]) describing the problem.
We now define this monadic encoding -- the ``state and error'' monad --
as well as convenient syntax to express monadic computations. *)
@@ -56,19 +61,19 @@ Record state: Set := mkstate {
Set Implicit Arguments.
Inductive res (A: Set) : Set :=
- | Error: res A
+ | Error: Errors.errmsg -> res A
| OK: A -> state -> res A.
Definition mon (A: Set) : Set := state -> res A.
Definition ret (A: Set) (x: A) : mon A := fun (s: state) => OK x s.
-Definition error (A: Set) : mon A := fun (s: state) => Error A.
+Definition error (A: Set) (msg: Errors.errmsg) : mon A := fun (s: state) => Error A msg.
Definition bind (A B: Set) (f: mon A) (g: A -> mon B) : mon B :=
fun (s: state) =>
match f s with
- | Error => Error B
+ | Error msg => Error B msg
| OK a s' => g a s'
end.
@@ -155,7 +160,7 @@ Definition update_instr (n: node) (i: instruction) : mon unit :=
(PTree.set n i s.(st_code))
(@update_instr_wf s n i PEQ))
| right _ =>
- Error unit
+ Error unit (Errors.msg "RTLgen.update_instr")
end.
(** Generate a fresh RTL register. *)
@@ -188,7 +193,7 @@ Fixpoint add_vars (map: mapping) (names: list ident)
Definition find_var (map: mapping) (name: ident) : mon reg :=
match PTree.get name map.(map_vars) with
- | None => error reg
+ | None => error reg (Errors.MSG "RTLgen: unbound variable " :: Errors.CTX name :: nil)
| Some r => ret r
end.
@@ -197,7 +202,7 @@ Definition add_letvar (map: mapping) (r: reg) : mapping :=
Definition find_letvar (map: mapping) (idx: nat) : mon reg :=
match List.nth_error map.(map_letvars) idx with
- | None => error reg
+ | None => error reg (Errors.msg "RTLgen: unbound let variable")
| Some r => ret r
end.
@@ -227,8 +232,8 @@ Fixpoint alloc_regs (map: mapping) (al: exprlist)
| Enil =>
ret nil
| Econs a bl =>
- do rl <- alloc_regs map bl;
do r <- alloc_reg map a;
+ do rl <- alloc_regs map bl;
ret (r :: rl)
end.
@@ -241,9 +246,9 @@ Definition add_move (rs rd: reg) (nd: node) : mon node :=
then ret nd
else add_instr (Iop Omove (rs::nil) rd nd).
-(** Translation of an expression. [transl_expr map mut a rd nd]
+(** Translation of an expression. [transl_expr map a rd nd]
enriches the current CFG with the RTL instructions necessary
- to compute the value of Cminor expression [a], leave its result
+ to compute the value of CminorSel expression [a], leave its result
in register [rd], and branch to node [nd]. It returns the node
of the first instruction in this sequence. [map] is the compile-time
translation environment. *)
@@ -311,7 +316,7 @@ with transl_condition (map: mapping) (a: condexpr) (ntrue nfalse: node)
end
(** Translation of a list of expressions. The expressions are evaluated
- left-to-right, and their values left in the given list of registers. *)
+ left-to-right, and their values stored in the given list of registers. *)
with transl_exprlist (map: mapping) (al: exprlist) (rl: list reg) (nd: node)
{struct al} : mon node :=
@@ -321,7 +326,7 @@ with transl_exprlist (map: mapping) (al: exprlist) (rl: list reg) (nd: node)
| Econs b bs, r :: rs =>
do no <- transl_exprlist map bs rs nd; transl_expr map b r no
| _, _ =>
- error node
+ error node (Errors.msg "RTLgen.transl_exprlist")
end.
(** Auxiliary for branch prediction. When compiling an if/then/else
@@ -336,27 +341,32 @@ Parameter more_likely: condexpr -> stmt -> stmt -> bool.
(** Auxiliary for translating [Sswitch] statements. *)
+Parameter compile_switch: nat -> table -> comptree.
+
Definition transl_exit (nexits: list node) (n: nat) : mon node :=
match nth_error nexits n with
- | None => error node
+ | None => error node (Errors.msg "RTLgen: wrong exit")
| Some ne => ret ne
end.
-Fixpoint transl_switch (r: reg) (nexits: list node)
- (cases: list (int * nat)) (default: nat)
- {struct cases} : mon node :=
- match cases with
- | nil =>
- transl_exit nexits default
- | (key1, exit1) :: cases' =>
- do ncont <- transl_switch r nexits cases' default;
- do nfound <- transl_exit nexits exit1;
- add_instr (Icond (Ccompimm Ceq key1) (r :: nil) nfound ncont)
+Fixpoint transl_switch (r: reg) (nexits: list node) (t: comptree)
+ {struct t} : mon node :=
+ match t with
+ | CTaction act =>
+ transl_exit nexits act
+ | CTifeq key act t' =>
+ do ncont <- transl_switch r nexits t';
+ do nfound <- transl_exit nexits act;
+ add_instr (Icond (Ccompimm Ceq key) (r :: nil) nfound ncont)
+ | CTiflt key t1 t2 =>
+ do n2 <- transl_switch r nexits t2;
+ do n1 <- transl_switch r nexits t1;
+ add_instr (Icond (Ccompuimm Clt key) (r :: nil) n1 n2)
end.
(** Translation of statements. [transl_stmt map s nd nexits nret rret]
enriches the current CFG with the RTL instructions necessary to
- execute the Cminor statement [s], and returns the node of the first
+ execute the CminorSel statement [s], and returns the node of the first
instruction in this sequence. The generated instructions continue
at node [nd] if the statement terminates normally, at node [nret]
if it terminates by early return, and at the [n]-th node in the list
@@ -398,18 +408,28 @@ Fixpoint transl_stmt (map: mapping) (s: stmt) (nd: node)
| Sexit n =>
transl_exit nexits n
| Sswitch a cases default =>
- do r <- alloc_reg map a;
- do ns <- transl_switch r nexits cases default;
- transl_expr map a r ns
+ let t := compile_switch default cases in
+ if validate_switch default cases t then
+ (do r <- alloc_reg map a;
+ do ns <- transl_switch r nexits t;
+ transl_expr map a r ns)
+ else
+ error node (Errors.msg "RTLgen: wrong switch")
| Sreturn opt_a =>
match opt_a, rret with
| None, None => ret nret
| Some a, Some r => transl_expr map a r nret
- | _, _ => error node
+ | _, _ => error node (Errors.msg "RTLgen: type mismatch on return")
end
+ | Stailcall sig b cl =>
+ do rf <- alloc_reg map b;
+ do rargs <- alloc_regs map cl;
+ do n1 <- add_instr (Itailcall sig (inl _ rf) rargs);
+ do n2 <- transl_exprlist map cl rargs n1;
+ transl_expr map b rf n2
end.
-(** Translation of a Cminor function. *)
+(** Translation of a CminorSel function. *)
Definition ret_reg (sig: signature) (rd: reg) : option reg :=
match sig.(sig_res) with
@@ -417,32 +437,32 @@ Definition ret_reg (sig: signature) (rd: reg) : option reg :=
| Some ty => Some rd
end.
-Definition transl_fun (f: Cminor.function) : mon (node * list reg) :=
- do (rparams, map1) <- add_vars init_mapping f.(Cminor.fn_params);
- do (rvars, map2) <- add_vars map1 f.(Cminor.fn_vars);
+Definition transl_fun (f: CminorSel.function) : mon (node * list reg) :=
+ do (rparams, map1) <- add_vars init_mapping f.(CminorSel.fn_params);
+ do (rvars, map2) <- add_vars map1 f.(CminorSel.fn_vars);
do rret <- new_reg;
- let orret := ret_reg f.(Cminor.fn_sig) rret in
+ let orret := ret_reg f.(CminorSel.fn_sig) rret in
do nret <- add_instr (Ireturn orret);
- do nentry <- transl_stmt map2 f.(Cminor.fn_body) nret nil nret orret;
+ do nentry <- transl_stmt map2 f.(CminorSel.fn_body) nret nil nret orret;
ret (nentry, rparams).
-Definition transl_function (f: Cminor.function) : option RTL.function :=
+Definition transl_function (f: CminorSel.function) : Errors.res RTL.function :=
match transl_fun f init_state with
- | Error => None
+ | Error msg => Errors.Error msg
| OK (nentry, rparams) s =>
- Some (RTL.mkfunction
- f.(Cminor.fn_sig)
- rparams
- f.(Cminor.fn_stackspace)
- s.(st_code)
- nentry
- s.(st_nextnode)
- s.(st_wf))
+ Errors.OK (RTL.mkfunction
+ f.(CminorSel.fn_sig)
+ rparams
+ f.(CminorSel.fn_stackspace)
+ s.(st_code)
+ nentry
+ s.(st_nextnode)
+ s.(st_wf))
end.
Definition transl_fundef := transf_partial_fundef transl_function.
(** Translation of a whole program. *)
-Definition transl_program (p: Cminor.program) : option RTL.program :=
+Definition transl_program (p: CminorSel.program) : Errors.res RTL.program :=
transform_partial_program transl_fundef p.
diff --git a/backend/RTLgenproof.v b/backend/RTLgenproof.v
index 2ce961b..15f305a 100644
--- a/backend/RTLgenproof.v
+++ b/backend/RTLgenproof.v
@@ -1,4 +1,4 @@
-(** Correctness proof for RTL generation: main proof. *)
+(** Correctness proof for RTL generation. *)
Require Import Coqlib.
Require Import Maps.
@@ -7,144 +7,411 @@ Require Import Integers.
Require Import Values.
Require Import Mem.
Require Import Events.
+Require Import Smallstep.
Require Import Globalenvs.
-Require Import Op.
+Require Import Switch.
Require Import Registers.
Require Import Cminor.
+Require Import Op.
+Require Import CminorSel.
Require Import RTL.
Require Import RTLgen.
-Require Import RTLgenproof1.
+Require Import RTLgenspec.
+
+(** * Correspondence between Cminor environments and RTL register sets *)
+
+(** A compilation environment (mapping) is well-formed if
+ the following properties hold:
+- Two distinct Cminor local variables are mapped to distinct pseudo-registers.
+- A Cminor local variable and a let-bound variable are mapped to
+ distinct pseudo-registers.
+*)
+
+Record map_wf (m: mapping) : Prop :=
+ mk_map_wf {
+ map_wf_inj:
+ (forall id1 id2 r,
+ m.(map_vars)!id1 = Some r -> m.(map_vars)!id2 = Some r -> id1 = id2);
+ map_wf_disj:
+ (forall id r,
+ m.(map_vars)!id = Some r -> In r m.(map_letvars) -> False)
+ }.
+
+Lemma init_mapping_wf:
+ map_wf init_mapping.
+Proof.
+ unfold init_mapping; split; simpl.
+ intros until r. rewrite PTree.gempty. congruence.
+ tauto.
+Qed.
+
+Lemma add_var_wf:
+ forall s1 s2 map name r map',
+ add_var map name s1 = OK (r,map') s2 ->
+ map_wf map -> map_valid map s1 -> map_wf map'.
+Proof.
+ intros. monadInv H.
+ apply mk_map_wf; simpl.
+ intros until r0. repeat rewrite PTree.gsspec.
+ destruct (peq id1 name); destruct (peq id2 name).
+ congruence.
+ intros. inv H. elimtype False.
+ apply valid_fresh_absurd with r0 s1.
+ apply H1. left; exists id2; auto.
+ eauto with rtlg.
+ intros. inv H2. elimtype False.
+ apply valid_fresh_absurd with r0 s1.
+ apply H1. left; exists id1; auto.
+ eauto with rtlg.
+ inv H0. eauto.
+ intros until r0. rewrite PTree.gsspec.
+ destruct (peq id name).
+ intros. inv H.
+ apply valid_fresh_absurd with r0 s1.
+ apply H1. right; auto.
+ eauto with rtlg.
+ inv H0; eauto.
+Qed.
+
+Lemma add_vars_wf:
+ forall names s1 s2 map map' rl,
+ add_vars map names s1 = OK (rl,map') s2 ->
+ map_wf map -> map_valid map s1 -> map_wf map'.
+Proof.
+ induction names; simpl; intros; monadInv H.
+ auto.
+ exploit add_vars_valid; eauto. intros [A B].
+ eapply add_var_wf; eauto.
+Qed.
+
+Lemma add_letvar_wf:
+ forall map r,
+ map_wf map -> ~reg_in_map map r -> map_wf (add_letvar map r).
+Proof.
+ intros. inv H. unfold add_letvar; constructor; simpl.
+ auto.
+ intros. elim H1; intro. subst r0. elim H0. left; exists id; auto.
+ eauto.
+Qed.
+
+(** An RTL register environment matches a Cminor local environment and
+ let-environment if the value of every local or let-bound variable in
+ the Cminor environments is identical to the value of the
+ corresponding pseudo-register in the RTL register environment. *)
+
+Record match_env
+ (map: mapping) (e: Cminor.env) (le: Cminor.letenv) (rs: regset) : Prop :=
+ mk_match_env {
+ me_vars:
+ (forall id v,
+ e!id = Some v -> exists r, map.(map_vars)!id = Some r /\ rs#r = v);
+ me_letvars:
+ rs##(map.(map_letvars)) = le
+ }.
+
+Lemma match_env_find_var:
+ forall map e le rs id v r,
+ match_env map e le rs ->
+ e!id = Some v ->
+ map.(map_vars)!id = Some r ->
+ rs#r = v.
+Proof.
+ intros. exploit me_vars; eauto. intros [r' [EQ' RS]].
+ replace r with r'. auto. congruence.
+Qed.
+
+Lemma match_env_find_letvar:
+ forall map e le rs idx v r,
+ match_env map e le rs ->
+ List.nth_error le idx = Some v ->
+ List.nth_error map.(map_letvars) idx = Some r ->
+ rs#r = v.
+Proof.
+ intros. exploit me_letvars; eauto. intros.
+ rewrite <- H2 in H0. rewrite list_map_nth in H0.
+ change reg with positive in H1. rewrite H1 in H0.
+ simpl in H0. congruence.
+Qed.
+
+Lemma match_env_invariant:
+ forall map e le rs rs',
+ match_env map e le rs ->
+ (forall r, (reg_in_map map r) -> rs'#r = rs#r) ->
+ match_env map e le rs'.
+Proof.
+ intros. inversion H. apply mk_match_env.
+ intros. exploit me_vars0; eauto. intros [r [A B]].
+ exists r; split. auto. rewrite H0; auto. left; exists id; auto.
+ rewrite <- me_letvars0. apply list_map_exten. intros.
+ symmetry. apply H0. right; auto.
+Qed.
+
+(** Matching between environments is preserved when an unmapped register
+ (not corresponding to any Cminor variable) is assigned in the RTL
+ execution. *)
+
+Lemma match_env_update_temp:
+ forall map e le rs r v,
+ match_env map e le rs ->
+ ~(reg_in_map map r) ->
+ match_env map e le (rs#r <- v).
+Proof.
+ intros. apply match_env_invariant with rs; auto.
+ intros. case (Reg.eq r r0); intro.
+ subst r0; contradiction.
+ apply Regmap.gso; auto.
+Qed.
+Hint Resolve match_env_update_temp: rtlg.
+
+(** Matching between environments is preserved by simultaneous
+ assignment to a Cminor local variable (in the Cminor environments)
+ and to the corresponding RTL pseudo-register (in the RTL register
+ environment). *)
+
+Lemma match_env_update_var:
+ forall map e le rs id r v,
+ map_wf map ->
+ map.(map_vars)!id = Some r ->
+ match_env map e le rs ->
+ match_env map (PTree.set id v e) le (rs#r <- v).
+Proof.
+ intros. inversion H. inversion H1. apply mk_match_env.
+ intros id' v'. rewrite PTree.gsspec. destruct (peq id' id); intros.
+ subst id'. inv H2. exists r; split. auto. apply PMap.gss.
+ exploit me_vars0; eauto. intros [r' [A B]].
+ exists r'; split. auto. rewrite PMap.gso; auto.
+ red; intros. subst r'. elim n. eauto.
+ rewrite <- me_letvars0. apply list_map_exten; intros.
+ symmetry. apply PMap.gso. red; intros. subst x. eauto.
+Qed.
+
+Lemma match_env_bind_letvar:
+ forall map e le rs r v,
+ match_env map e le rs ->
+ rs#r = v ->
+ match_env (add_letvar map r) e (v :: le) rs.
+Proof.
+ intros. inv H. unfold add_letvar. apply mk_match_env; simpl; auto.
+Qed.
+
+Lemma match_env_unbind_letvar:
+ forall map e le rs r v,
+ match_env (add_letvar map r) e (v :: le) rs ->
+ match_env map e le rs.
+Proof.
+ unfold add_letvar; intros. inv H. simpl in *.
+ constructor. auto. congruence.
+Qed.
+
+Lemma match_env_empty:
+ forall map,
+ map.(map_letvars) = nil ->
+ match_env map (PTree.empty val) nil (Regmap.init Vundef).
+Proof.
+ intros. apply mk_match_env.
+ intros. rewrite PTree.gempty in H0. discriminate.
+ rewrite H. reflexivity.
+Qed.
+
+(** The assignment of function arguments to local variables (on the Cminor
+ side) and pseudo-registers (on the RTL side) preserves matching
+ between environments. *)
+
+Lemma match_set_params_init_regs:
+ forall il rl s1 map2 s2 vl,
+ add_vars init_mapping il s1 = OK (rl, map2) s2 ->
+ match_env map2 (set_params vl il) nil (init_regs vl rl)
+ /\ (forall r, reg_fresh r s2 -> (init_regs vl rl)#r = Vundef).
+Proof.
+ induction il; intros.
+
+ inv H. split. apply match_env_empty. auto. intros.
+ simpl. apply Regmap.gi.
+
+ monadInv H. simpl.
+ exploit add_vars_valid; eauto. apply init_mapping_valid. intros [A B].
+ exploit add_var_valid; eauto. intros [A' B']. clear B'.
+ monadInv EQ1.
+ destruct vl as [ | v1 vs].
+ (* vl = nil *)
+ destruct (IHil _ _ _ _ nil EQ) as [ME UNDEF]. inv ME. split.
+ constructor; simpl.
+ intros id v. repeat rewrite PTree.gsspec. destruct (peq id a); intros.
+ subst a. inv H. exists x1; split. auto. apply Regmap.gi.
+ replace (init_regs nil x) with (Regmap.init Vundef) in me_vars0. eauto.
+ destruct x; reflexivity.
+ destruct (map_letvars x0). auto. simpl in me_letvars0. congruence.
+ intros. apply Regmap.gi.
+ (* vl = v1 :: vs *)
+ destruct (IHil _ _ _ _ vs EQ) as [ME UNDEF]. inv ME. split.
+ constructor; simpl.
+ intros id v. repeat rewrite PTree.gsspec. destruct (peq id a); intros.
+ subst a. inv H. exists x1; split. auto. apply Regmap.gss.
+ exploit me_vars0; eauto. intros [r' [C D]].
+ exists r'; split. auto. rewrite Regmap.gso. auto.
+ apply valid_fresh_different with s.
+ apply B. left; exists id; auto.
+ eauto with rtlg.
+ destruct (map_letvars x0). auto. simpl in me_letvars0. congruence.
+ intros. rewrite Regmap.gso. apply UNDEF.
+ apply reg_fresh_decr with s2; eauto with rtlg.
+ apply sym_not_equal. apply valid_fresh_different with s2; auto.
+Qed.
+
+Lemma match_set_locals:
+ forall map1 s1,
+ map_wf map1 ->
+ forall il rl map2 s2 e le rs,
+ match_env map1 e le rs ->
+ (forall r, reg_fresh r s1 -> rs#r = Vundef) ->
+ add_vars map1 il s1 = OK (rl, map2) s2 ->
+ match_env map2 (set_locals il e) le rs.
+Proof.
+ induction il; simpl in *; intros.
+
+ inv H2. auto.
+
+ monadInv H2.
+ exploit IHil; eauto. intro.
+ monadInv EQ1.
+ constructor.
+ intros id v. simpl. repeat rewrite PTree.gsspec.
+ destruct (peq id a). subst a. intro.
+ exists x1. split. auto. inv H3.
+ apply H1. apply reg_fresh_decr with s.
+ eapply add_vars_incr; eauto.
+ eauto with rtlg.
+ intros. eapply me_vars; eauto.
+ simpl. eapply me_letvars; eauto.
+Qed.
+
+Lemma match_init_env_init_reg:
+ forall params s0 rparams map1 s1 vars rvars map2 s2 vparams,
+ add_vars init_mapping params s0 = OK (rparams, map1) s1 ->
+ add_vars map1 vars s1 = OK (rvars, map2) s2 ->
+ match_env map2 (set_locals vars (set_params vparams params))
+ nil (init_regs vparams rparams).
+Proof.
+ intros.
+ exploit match_set_params_init_regs; eauto. intros [A B].
+ eapply match_set_locals; eauto.
+ eapply add_vars_wf; eauto. apply init_mapping_wf.
+ apply init_mapping_valid.
+Qed.
+
+(** * The simulation argument *)
+
+Require Import Errors.
Section CORRECTNESS.
-Variable prog: Cminor.program.
+Variable prog: CminorSel.program.
Variable tprog: RTL.program.
-Hypothesis TRANSL: transl_program prog = Some tprog.
+Hypothesis TRANSL: transl_program prog = OK tprog.
-Let ge : Cminor.genv := Genv.globalenv prog.
+Let ge : CminorSel.genv := Genv.globalenv prog.
Let tge : RTL.genv := Genv.globalenv tprog.
(** Relationship between the global environments for the original
- Cminor program and the generated RTL program. *)
+ CminorSel program and the generated RTL program. *)
Lemma symbols_preserved:
forall (s: ident), Genv.find_symbol tge s = Genv.find_symbol ge s.
-Proof.
- intro. unfold ge, tge.
- apply Genv.find_symbol_transf_partial with transl_fundef.
- exact TRANSL.
-Qed.
+Proof
+ (Genv.find_symbol_transf_partial transl_fundef _ TRANSL).
Lemma function_ptr_translated:
- forall (b: block) (f: Cminor.fundef),
+ forall (b: block) (f: CminorSel.fundef),
Genv.find_funct_ptr ge b = Some f ->
exists tf,
- Genv.find_funct_ptr tge b = Some tf /\ transl_fundef f = Some tf.
-Proof.
- intros.
- generalize
- (Genv.find_funct_ptr_transf_partial transl_fundef TRANSL H).
- case (transl_fundef f).
- intros tf [A B]. exists tf. tauto.
- intros [A B]. elim B. reflexivity.
-Qed.
+ Genv.find_funct_ptr tge b = Some tf /\ transl_fundef f = OK tf.
+Proof
+ (Genv.find_funct_ptr_transf_partial transl_fundef TRANSL).
Lemma functions_translated:
- forall (v: val) (f: Cminor.fundef),
+ forall (v: val) (f: CminorSel.fundef),
Genv.find_funct ge v = Some f ->
exists tf,
- Genv.find_funct tge v = Some tf /\ transl_fundef f = Some tf.
-Proof.
- intros.
- generalize
- (Genv.find_funct_transf_partial transl_fundef TRANSL H).
- case (transl_fundef f).
- intros tf [A B]. exists tf. tauto.
- intros [A B]. elim B. reflexivity.
-Qed.
+ Genv.find_funct tge v = Some tf /\ transl_fundef f = OK tf.
+Proof
+ (Genv.find_funct_transf_partial transl_fundef TRANSL).
Lemma sig_transl_function:
- forall (f: Cminor.fundef) (tf: RTL.fundef),
- transl_fundef f = Some tf ->
- RTL.funsig tf = Cminor.funsig f.
+ forall (f: CminorSel.fundef) (tf: RTL.fundef),
+ transl_fundef f = OK tf ->
+ RTL.funsig tf = CminorSel.funsig f.
Proof.
intros until tf. unfold transl_fundef, transf_partial_fundef.
case f; intro.
unfold transl_function.
- case (transl_fun f0 init_state); intros.
+ case (transl_fun f0 init_state); simpl; intros.
discriminate.
- destruct p. inversion H. reflexivity.
+ destruct p. simpl in H. inversion H. reflexivity.
intro. inversion H. reflexivity.
Qed.
(** Correctness of the code generated by [add_move]. *)
-Lemma add_move_correct:
- forall r1 r2 sp nd s ns s' rs m,
- add_move r1 r2 nd s = OK ns s' ->
+Lemma tr_move_correct:
+ forall r1 ns r2 nd cs code sp rs m,
+ tr_move code ns r1 nd r2 ->
exists rs',
- exec_instrs tge s'.(st_code) sp ns rs m E0 nd rs' m /\
+ star step tge (State cs code sp ns rs m) E0 (State cs code sp nd rs' m) /\
rs'#r2 = rs#r1 /\
(forall r, r <> r2 -> rs'#r = rs#r).
Proof.
- intros until m.
- unfold add_move. case (Reg.eq r1 r2); intro.
- monadSimpl. subst s'; subst r2; subst ns.
- exists rs. split. apply exec_refl. split. auto. auto.
- intro. exists (rs#r2 <- (rs#r1)).
- split. apply exec_one. eapply exec_Iop. eauto with rtlg.
- reflexivity.
- split. apply Regmap.gss.
- intros. apply Regmap.gso; auto.
+ intros. inv H.
+ exists rs; split. constructor. auto.
+ exists (rs#r2 <- (rs#r1)); split.
+ apply star_one. eapply exec_Iop. eauto. auto.
+ split. apply Regmap.gss. intros; apply Regmap.gso; auto.
Qed.
(** The proof of semantic preservation for the translation of expressions
is a simulation argument based on diagrams of the following form:
<<
I /\ P
- e, m, a ------------- ns, rs, m
+ e, le, m, a ------------- State cs code sp ns rs m
|| |
- || |*
+ t|| t|*
|| |
\/ v
- e', m', v ----------- nd, rs', m'
+ e, le, m', v ------------ State cs code sp nd rs' m'
I /\ Q
>>
- where [transl_expr map mut a rd nd s = OK ns s'].
+ where [tr_expr code map pr a ns nd rd] is assumed to hold.
The left vertical arrow represents an evaluation of the expression [a]
- (assumption). The right vertical arrow represents the execution of
- zero, one or several instructions in the generated RTL flow graph
- found in the final state [s'] (conclusion).
+ to value [v].
+ The right vertical arrow represents the execution of zero, one or
+ several instructions in the generated RTL flow graph [code].
- The invariant [I] is the agreement between Cminor environments and
- RTL register environment, as captured by [match_envs].
+ The invariant [I] is the agreement between CminorSel environments
+ [e], [le] and the RTL register environment [rs],
+ as captured by [match_envs].
- The preconditions [P] include the well-formedness of the compilation
- environment [mut] and the validity of [rd] as a target register.
+ The precondition [P] is the well-formedness of the compilation
+ environment [mut].
The postconditions [Q] state that in the final register environment
- [rs'], register [rd] contains value [v], and most other registers
- valid in [s] are unchanged w.r.t. the initial register environment
- [rs]. (See below for a precise specification of ``most other
- registers''.)
+ [rs'], register [rd] contains value [v], and the registers in
+ the set of preserved registers [pr] are unchanged, as are the registers
+ in the codomain of [map].
We formalize this simulation property by the following predicate
- parameterized by the Cminor evaluation (left arrow). *)
+ parameterized by the CminorSel evaluation (left arrow). *)
Definition transl_expr_correct
(sp: val) (le: letenv) (e: env) (m: mem) (a: expr)
(t: trace) (m': mem) (v: val) : Prop :=
- forall map rd nd s ns s' rs
- (MWF: map_wf map s)
- (TE: transl_expr map a rd nd s = OK ns s')
- (ME: match_env map e le rs)
- (TRG: target_reg_ok s map a rd),
+ forall cs code map pr ns nd rd rs
+ (MWF: map_wf map)
+ (TE: tr_expr code map pr a ns nd rd)
+ (ME: match_env map e le rs),
exists rs',
- exec_instrs tge s'.(st_code) sp ns rs m t nd rs' m'
+ star step tge (State cs code sp ns rs m) t (State cs code sp nd rs' m')
/\ match_env map e le rs'
/\ rs'#rd = v
- /\ (forall r,
- reg_valid r s -> reg_in_map map r \/ r <> rd -> rs'#r = rs#r).
+ /\ (forall r, reg_in_map map r \/ In r pr -> rs'#r = rs#r).
(** The simulation properties for lists of expressions and for
conditional expressions are similar. *)
@@ -152,122 +419,113 @@ Definition transl_expr_correct
Definition transl_exprlist_correct
(sp: val) (le: letenv) (e: env) (m: mem) (al: exprlist)
(t: trace) (m': mem) (vl: list val) : Prop :=
- forall map rl nd s ns s' rs
- (MWF: map_wf map s)
- (TE: transl_exprlist map al rl nd s = OK ns s')
- (ME: match_env map e le rs)
- (TRG: target_regs_ok s map al rl),
+ forall cs code map pr ns nd rl rs
+ (MWF: map_wf map)
+ (TE: tr_exprlist code map pr al ns nd rl)
+ (ME: match_env map e le rs),
exists rs',
- exec_instrs tge s'.(st_code) sp ns rs m t nd rs' m'
+ star step tge (State cs code sp ns rs m) t (State cs code sp nd rs' m')
/\ match_env map e le rs'
/\ rs'##rl = vl
- /\ (forall r,
- reg_valid r s -> reg_in_map map r \/ ~(In r rl) -> rs'#r = rs#r).
+ /\ (forall r, reg_in_map map r \/ In r pr -> rs'#r = rs#r).
Definition transl_condition_correct
(sp: val) (le: letenv) (e: env) (m: mem) (a: condexpr)
(t: trace) (m': mem) (vb: bool) : Prop :=
- forall map ntrue nfalse s ns s' rs
- (MWF: map_wf map s)
- (TE: transl_condition map a ntrue nfalse s = OK ns s')
+ forall cs code map pr ns ntrue nfalse rs
+ (MWF: map_wf map)
+ (TE: tr_condition code map pr a ns ntrue nfalse)
(ME: match_env map e le rs),
exists rs',
- exec_instrs tge s'.(st_code) sp ns rs m t (if vb then ntrue else nfalse) rs' m'
+ star step tge (State cs code sp ns rs m) t
+ (State cs code sp (if vb then ntrue else nfalse) rs' m')
/\ match_env map e le rs'
- /\ (forall r, reg_valid r s -> rs'#r = rs#r).
-
-(** For statements, we define the following auxiliary predicates
- relating the outcome of the Cminor execution with the final node
- and value of the return register in the RTL execution. *)
-
-Definition outcome_node
- (out: outcome)
- (ncont: node) (nexits: list node) (nret: node) (nd: node) : Prop :=
- match out with
- | Out_normal => ncont = nd
- | Out_exit n => nth_error nexits n = Some nd
- | Out_return _ => nret = nd
- end.
-
-Definition match_return_reg
- (rs: regset) (rret: option reg) (v: val) : Prop :=
- match rret with
- | None => True
- | Some r => rs#r = v
- end.
-
-Definition match_return_outcome
- (out: outcome) (rret: option reg) (rs: regset) : Prop :=
- match out with
- | Out_normal => True
- | Out_exit n => True
- | Out_return optv =>
- match rret, optv with
- | None, None => True
- | Some r, Some v => rs#r = v
- | _, _ => False
- end
- end.
+ /\ (forall r, reg_in_map map r \/ In r pr -> rs'#r = rs#r).
+
(** The simulation diagram for the translation of statements
is of the following form:
<<
I /\ P
- e, m, a ------------- ns, rs, m
+ e, m, a -------------- State cs code sp ns rs m
|| |
- || |*
+ t|| t|*
|| |
\/ v
- e', m', out --------- nd, rs', m'
+ e', m', out -------------- st'
I /\ Q
>>
- where [transl_stmt map a ncont nexits nret rret s = OK ns s'].
+ where [tr_stmt code map a ns ncont nexits nret rret] holds.
The left vertical arrow represents an execution of the statement [a]
- (assumption). The right vertical arrow represents the execution of
- zero, one or several instructions in the generated RTL flow graph
- found in the final state [s'] (conclusion).
+ with outcome [out].
+ The right vertical arrow represents the execution of
+ zero, one or several instructions in the generated RTL flow graph [code].
- The invariant [I] is the agreement between Cminor environments and
+ The invariant [I] is the agreement between CminorSel environments and
RTL register environment, as captured by [match_envs].
- The preconditions [P] include the well-formedness of the compilation
- environment [mut] and the agreement between the outcome [out]
- and the end node [nd].
-
- The postcondition [Q] states agreement between the outcome [out]
- and the value of the return register [rret]. *)
+ The precondition [P] is the well-formedness of the compilation
+ environment [mut].
+
+ The postcondition [Q] characterizes the final RTL state [st'].
+ It must have memory state [m'] and a register state [rs'] that matches
+ [e']. Moreover, the program point reached must correspond to the outcome
+ [out]. This is captured by the following [state_for_outcome] predicate. *)
+
+Inductive state_for_outcome
+ (ncont: node) (nexits: list node) (nret: node) (rret: option reg)
+ (cs: list stackframe) (c: code) (sp: val) (rs: regset) (m: mem):
+ outcome -> RTL.state -> Prop :=
+ | state_for_normal:
+ state_for_outcome ncont nexits nret rret cs c sp rs m
+ Out_normal (State cs c sp ncont rs m)
+ | state_for_exit: forall n nexit,
+ nth_error nexits n = Some nexit ->
+ state_for_outcome ncont nexits nret rret cs c sp rs m
+ (Out_exit n) (State cs c sp nexit rs m)
+ | state_for_return_none:
+ rret = None ->
+ state_for_outcome ncont nexits nret rret cs c sp rs m
+ (Out_return None) (State cs c sp nret rs m)
+ | state_for_return_some: forall r v,
+ rret = Some r ->
+ rs#r = v ->
+ state_for_outcome ncont nexits nret rret cs c sp rs m
+ (Out_return (Some v)) (State cs c sp nret rs m)
+ | state_for_return_tail: forall v,
+ state_for_outcome ncont nexits nret rret cs c sp rs m
+ (Out_tailcall_return v) (Returnstate cs v m).
Definition transl_stmt_correct
(sp: val) (e: env) (m: mem) (a: stmt)
(t: trace) (e': env) (m': mem) (out: outcome) : Prop :=
- forall map ncont nexits nret rret s ns s' nd rs
- (MWF: map_wf map s)
- (TE: transl_stmt map a ncont nexits nret rret s = OK ns s')
- (ME: match_env map e nil rs)
- (OUT: outcome_node out ncont nexits nret nd)
- (RRG: return_reg_ok s map rret),
- exists rs',
- exec_instrs tge s'.(st_code) sp ns rs m t nd rs' m'
- /\ match_env map e' nil rs'
- /\ match_return_outcome out rret rs'.
+ forall cs code map ns ncont nexits nret rret rs
+ (MWF: map_wf map)
+ (TE: tr_stmt code map a ns ncont nexits nret rret)
+ (ME: match_env map e nil rs),
+ exists rs', exists st,
+ state_for_outcome ncont nexits nret rret cs code sp rs' m' out st
+ /\ star step tge (State cs code sp ns rs m) t st
+ /\ match_env map e' nil rs'.
(** Finally, the correctness condition for the translation of functions
is that the translated RTL function, when applied to the same arguments
- as the original Cminor function, returns the same value and performs
- the same modifications on the memory state. *)
+ as the original CminorSel function, returns the same value, produces
+ the same trace of events, and performs the same modifications on the
+ memory state. *)
Definition transl_function_correct
- (m: mem) (f: Cminor.fundef) (vargs: list val)
- (t: trace) (m':mem) (vres: val) : Prop :=
- forall tf
- (TE: transl_fundef f = Some tf),
- exec_function tge tf vargs m t vres m'.
+ (m: mem) (f: CminorSel.fundef) (vargs: list val)
+ (t: trace) (m': mem) (vres: val) : Prop :=
+ forall cs tf
+ (TE: transl_fundef f = OK tf),
+ star step tge (Callstate cs tf vargs m) t (Returnstate cs vres m').
(** The correctness of the translation is a huge induction over
- the Cminor evaluation derivation for the source program. To keep
+ the CminorSel evaluation derivation for the source program. To keep
the proof manageable, we put each case of the proof in a separate
- lemma. There is one lemma for each Cminor evaluation rule.
- It takes as hypotheses the premises of the Cminor evaluation rule,
+ lemma. There is one lemma for each CminorSel evaluation rule.
+ It takes as hypotheses the premises of the CminorSel evaluation rule,
plus the induction hypotheses, that is, the [transl_expr_correct], etc,
corresponding to the evaluations of sub-expressions or sub-statements. *)
@@ -276,35 +534,22 @@ Lemma transl_expr_Evar_correct:
e!id = Some v ->
transl_expr_correct sp le e m (Evar id) E0 m v.
Proof.
- intros; red; intros. monadInv TE. intro.
- generalize EQ; unfold find_var. caseEq (map_vars map)!id.
- intros r' MV; monadSimpl. subst s0; subst r'.
- generalize (add_move_correct _ _ sp _ _ _ _ rs m TE0).
- intros [rs1 [EX1 [RES1 OTHER1]]].
- exists rs1.
-(* Exec *)
- split. assumption.
-(* Match-env *)
- split. inversion TRG; subst.
- (* Optimized case rd = r *)
- rewrite MV in H3; injection H3; intro; subst r.
- apply match_env_exten with rs.
- intros. case (Reg.eq r rd); intro.
- subst r; assumption. apply OTHER1; assumption.
- assumption.
- (* General case rd is temp *)
- apply match_env_invariant with rs.
- assumption. intros. apply OTHER1. congruence.
-(* Result value *)
- split. rewrite RES1. eauto with rtlg.
-(* Other regs *)
- intros. destruct (Reg.eq rd r0).
- subst r0. inversion TRG; subst.
- congruence.
- byContradiction. tauto.
+ intros; red; intros. inv TE.
+ exploit tr_move_correct; eauto. intros [rs' [A [B C]]].
+ exists rs'; split. eauto.
+ destruct H2 as [D | [E F]].
+ (* optimized case *)
+ subst r.
+ assert (forall r, rs'#r = rs#r).
+ intros. destruct (Reg.eq r rd). subst r. auto. auto.
+ split. eapply match_env_invariant; eauto.
+ split. rewrite B. eapply match_env_find_var; eauto.
auto.
-
- intro; monadSimpl.
+ (* general case *)
+ split. eapply match_env_invariant; eauto.
+ intros. apply C. congruence.
+ split. rewrite B. eapply match_env_find_var; eauto.
+ intros. apply C. intuition congruence.
Qed.
Lemma transl_expr_Eop_correct:
@@ -313,36 +558,25 @@ Lemma transl_expr_Eop_correct:
(v: val),
eval_exprlist ge sp le e m al t m1 vl ->
transl_exprlist_correct sp le e m al t m1 vl ->
- eval_operation ge sp op vl = Some v ->
+ eval_operation ge sp op vl m1 = Some v ->
transl_expr_correct sp le e m (Eop op al) t m1 v.
Proof.
- intros until v. intros EEL TEL EOP. red; intros.
- simpl in TE. monadInv TE. intro EQ1.
- exploit TEL. 2: eauto. eauto with rtlg. eauto. eauto with rtlg.
- intros [rs1 [EX1 [ME1 [RR1 RO1]]]].
+ intros; red; intros. inv TE.
+ exploit H0; eauto. intros [rs1 [EX1 [ME1 [RR1 RO1]]]].
exists (rs1#rd <- v).
(* Exec *)
- split. eapply exec_trans. eexact EX1.
- apply exec_instrs_incr with s1. eauto with rtlg.
- apply exec_one; eapply exec_Iop. eauto with rtlg.
+ split. eapply star_right. eexact EX1.
+ eapply exec_Iop; eauto.
subst vl.
- rewrite (@eval_operation_preserved Cminor.fundef RTL.fundef ge tge).
- eexact EOP.
+ rewrite (@eval_operation_preserved CminorSel.fundef RTL.fundef ge tge).
+ auto.
exact symbols_preserved. traceEq.
(* Match-env *)
- split. inversion TRG. eauto with rtlg.
+ split. eauto with rtlg.
(* Result reg *)
split. apply Regmap.gss.
(* Other regs *)
- intros. rewrite Regmap.gso.
- apply RO1. eauto with rtlg.
- destruct (In_dec Reg.eq r l).
- left. elim (alloc_regs_fresh_or_in_map _ _ _ _ _ MWF EQ r i); intro.
- auto. byContradiction; eauto with rtlg.
- right; auto.
- red; intro; subst r.
- elim H0; intro. inversion TRG. contradiction.
- tauto.
+ intros. rewrite Regmap.gso. auto. intuition congruence.
Qed.
Lemma transl_expr_Eload_correct:
@@ -356,30 +590,19 @@ Lemma transl_expr_Eload_correct:
Mem.loadv chunk m1 a = Some v ->
transl_expr_correct sp le e m (Eload chunk addr al) t m1 v.
Proof.
- intros; red; intros. simpl in TE. monadInv TE. intro EQ1. clear TE.
- assert (MWF1: map_wf map s1). eauto with rtlg.
- assert (TRG1: target_regs_ok s1 map al l). eauto with rtlg.
- generalize (H0 _ _ _ _ _ _ _ MWF1 EQ1 ME TRG1).
- intros [rs1 [EX1 [ME1 [RES1 OTHER1]]]].
+ intros; red; intros. inv TE.
+ exploit H0; eauto. intros [rs1 [EX1 [ME1 [RES1 OTHER1]]]].
exists (rs1#rd <- v).
(* Exec *)
- split. eapply exec_trans. eexact EX1.
- apply exec_instrs_incr with s1. eauto with rtlg.
- apply exec_one. eapply exec_Iload. eauto with rtlg.
+ split. eapply star_right. eexact EX1. eapply exec_Iload; eauto.
rewrite RES1. rewrite (@eval_addressing_preserved _ _ ge tge).
- eexact H1. exact symbols_preserved. assumption. traceEq.
+ exact H1. exact symbols_preserved. traceEq.
(* Match-env *)
- split. eapply match_env_update_temp. assumption. inversion TRG. assumption.
+ split. eauto with rtlg.
(* Result *)
split. apply Regmap.gss.
(* Other regs *)
- intros. rewrite Regmap.gso. apply OTHER1.
- eauto with rtlg.
- case (In_dec Reg.eq r l); intro.
- elim (alloc_regs_fresh_or_in_map _ _ _ _ _ MWF EQ r i); intro.
- tauto. byContradiction. eauto with rtlg.
- tauto.
- red; intro; subst r. inversion TRG. tauto.
+ intros. rewrite Regmap.gso. auto. intuition congruence.
Qed.
Lemma transl_expr_Estore_correct:
@@ -397,35 +620,18 @@ Lemma transl_expr_Estore_correct:
t = t1 ** t2 ->
transl_expr_correct sp le e m (Estore chunk addr al b) t m3 v.
Proof.
- intros; red; intros. simpl in TE; monadInv TE. intro EQ2; clear TE.
- assert (MWF2: map_wf map s2).
- apply map_wf_incr with s.
- apply state_incr_trans2 with s0 s1; eauto with rtlg.
- assumption.
- assert (TRG2: target_regs_ok s2 map al l).
- apply target_regs_ok_incr with s0; eauto with rtlg.
- generalize (H0 _ _ _ _ _ _ _ MWF2 EQ2 ME TRG2).
- intros [rs1 [EX1 [ME1 [RES1 OTHER1]]]].
- assert (MWF1: map_wf map s1). eauto with rtlg.
- assert (TRG1: target_reg_ok s1 map b rd).
- inversion TRG. apply target_reg_other; eauto with rtlg.
- generalize (H2 _ _ _ _ _ _ _ MWF1 EQ1 ME1 TRG1).
- intros [rs2 [EX2 [ME2 [RES2 OTHER2]]]].
+ intros; red; intros; inv TE.
+ exploit H0; eauto. intros [rs1 [EX1 [ME1 [RES1 OTHER1]]]].
+ exploit H2; eauto. intros [rs2 [EX2 [ME2 [RES2 OTHER2]]]].
exists rs2.
(* Exec *)
- split. eapply exec_trans. eexact EX1.
- apply exec_instrs_incr with s2. eauto with rtlg.
- eapply exec_trans. eexact EX2.
- apply exec_instrs_incr with s1. eauto with rtlg.
- apply exec_one. eapply exec_Istore. eauto with rtlg.
- assert (rs2##l = rs1##l).
+ split. eapply star_trans. eexact EX1.
+ eapply star_right. eexact EX2.
+ eapply exec_Istore; eauto.
+ assert (rs2##rl = rs1##rl).
apply list_map_exten. intros r' IN. symmetry. apply OTHER2.
- eauto with rtlg. eauto with rtlg.
- elim (alloc_regs_fresh_or_in_map _ _ _ _ _ MWF EQ r' IN); intro.
- tauto. right. apply sym_not_equal.
- apply valid_fresh_different with s. inversion TRG; assumption.
- assumption.
- rewrite H6; rewrite RES1.
+ right. apply in_or_app. auto.
+ rewrite H5; rewrite RES1.
rewrite (@eval_addressing_preserved _ _ ge tge).
eexact H3. exact symbols_preserved.
rewrite RES2. assumption.
@@ -435,110 +641,52 @@ Proof.
(* Result *)
split. assumption.
(* Other regs *)
- intro r'; intros. transitivity (rs1#r').
- apply OTHER2. apply reg_valid_incr with s; eauto with rtlg.
- assumption.
- apply OTHER1. apply reg_valid_incr with s.
- apply state_incr_trans2 with s0 s1; eauto with rtlg. assumption.
- case (In_dec Reg.eq r' l); intro.
- elim (alloc_regs_fresh_or_in_map _ _ _ _ _ MWF EQ r' i); intro.
- tauto. byContradiction; eauto with rtlg. tauto.
-Qed.
+ intro r'; intros. transitivity (rs1#r').
+ apply OTHER2. intuition.
+ auto.
+Qed.
Lemma transl_expr_Ecall_correct:
forall (sp: val) (le : letenv) (e : env) (m : mem)
(sig : signature) (a : expr) (bl : exprlist) (t t1: trace)
(m1: mem) (t2: trace) (m2 : mem)
(t3: trace) (m3: mem) (vf : val)
- (vargs : list val) (vres : val) (f : Cminor.fundef),
+ (vargs : list val) (vres : val) (f : CminorSel.fundef),
eval_expr ge sp le e m a t1 m1 vf ->
transl_expr_correct sp le e m a t1 m1 vf ->
eval_exprlist ge sp le e m1 bl t2 m2 vargs ->
transl_exprlist_correct sp le e m1 bl t2 m2 vargs ->
Genv.find_funct ge vf = Some f ->
- Cminor.funsig f = sig ->
+ CminorSel.funsig f = sig ->
eval_funcall ge m2 f vargs t3 m3 vres ->
transl_function_correct m2 f vargs t3 m3 vres ->
t = t1 ** t2 ** t3 ->
transl_expr_correct sp le e m (Ecall sig a bl) t m3 vres.
Proof.
- intros. red; simpl; intros.
- monadInv TE. intro EQ3. clear TE.
- assert (MWFa: map_wf map s3).
- apply map_wf_incr with s.
- apply state_incr_trans3 with s0 s1 s2; eauto with rtlg.
- assumption.
- assert (TRGr: target_reg_ok s3 map a r).
- apply target_reg_ok_incr with s0.
- apply state_incr_trans2 with s1 s2; eauto with rtlg.
- eauto with rtlg.
- generalize (H0 _ _ _ _ _ _ _ MWFa EQ3 ME TRGr).
- intros [rs1 [EX1 [ME1 [RES1 OTHER1]]]].
- clear MWFa TRGr.
- assert (MWFbl: map_wf map s2).
- apply map_wf_incr with s.
- apply state_incr_trans2 with s0 s1; eauto with rtlg.
- assumption.
- assert (TRGl: target_regs_ok s2 map bl l).
- apply target_regs_ok_incr with s1; eauto with rtlg.
- generalize (H2 _ _ _ _ _ _ _ MWFbl EQ2 ME1 TRGl).
- intros [rs2 [EX2 [ME2 [RES2 OTHER2]]]].
- clear MWFbl TRGl.
-
- generalize (functions_translated vf f H3). intros [tf [TFIND TF]].
- generalize (H6 tf TF). intro EXF.
-
- assert (EX3: exec_instrs tge (st_code s2) sp n rs2 m2
- t3 nd (rs2#rd <- vres) m3).
- apply exec_one. eapply exec_Icall.
- eauto with rtlg. simpl. replace (rs2#r) with vf. eexact TFIND.
- rewrite <- RES1. symmetry. apply OTHER2.
- apply reg_valid_incr with s0; eauto with rtlg.
- assert (MWFs0: map_wf map s0). eauto with rtlg.
- case (In_dec Reg.eq r l); intro.
- elim (alloc_regs_fresh_or_in_map _ _ _ _ _ MWFs0 EQ0 r i); intro.
- tauto. byContradiction. apply valid_fresh_absurd with r s0.
- eauto with rtlg. assumption.
- tauto.
- generalize (sig_transl_function _ _ TF). congruence.
- rewrite RES2. assumption.
-
+ intros; red; intros; inv TE.
+ exploit H0; eauto. intros [rs1 [EX1 [ME1 [RES1 OTHER1]]]].
+ exploit H2; eauto. intros [rs2 [EX2 [ME2 [RES2 OTHER2]]]].
+ exploit functions_translated; eauto. intros [tf [TFIND TF]].
+ exploit H6; eauto. intro EXF.
exists (rs2#rd <- vres).
(* Exec *)
- split. eapply exec_trans. eexact EX1.
- apply exec_instrs_incr with s3. eauto with rtlg.
- eapply exec_trans. eexact EX2.
- apply exec_instrs_incr with s2. eauto with rtlg.
- eexact EX3. reflexivity. traceEq.
+ split. eapply star_trans. eexact EX1.
+ eapply star_trans. eexact EX2.
+ eapply star_left. eapply exec_Icall; eauto.
+ simpl. rewrite OTHER2. rewrite RES1. eauto. simpl; tauto.
+ eapply sig_transl_function; eauto.
+ eapply star_right. rewrite RES2. eexact EXF.
+ apply exec_return. reflexivity. reflexivity. reflexivity. traceEq.
(* Match env *)
- split. apply match_env_update_temp. assumption.
- inversion TRG. assumption.
+ split. eauto with rtlg.
(* Result *)
split. apply Regmap.gss.
(* Other regs *)
intros.
- rewrite Regmap.gso. transitivity (rs1#r0).
- apply OTHER2.
- apply reg_valid_incr with s.
- apply state_incr_trans2 with s0 s1; eauto with rtlg.
- assumption.
- assert (MWFs0: map_wf map s0). eauto with rtlg.
- case (In_dec Reg.eq r0 l); intro.
- elim (alloc_regs_fresh_or_in_map _ _ _ _ _ MWFs0 EQ0 r0 i); intro.
- tauto. byContradiction. apply valid_fresh_absurd with r0 s0.
- eauto with rtlg. assumption.
- tauto.
- apply OTHER1.
- apply reg_valid_incr with s.
- apply state_incr_trans3 with s0 s1 s2; eauto with rtlg.
- assumption.
- case (Reg.eq r0 r); intro.
- subst r0.
- elim (alloc_reg_fresh_or_in_map _ _ _ _ _ MWF EQ); intro.
- tauto. byContradiction; eauto with rtlg.
- tauto.
- red; intro; subst r0.
- inversion TRG. tauto.
+ rewrite Regmap.gso. transitivity (rs1#r).
+ apply OTHER2. simpl; tauto.
+ apply OTHER1; auto.
+ intuition congruence.
Qed.
Lemma transl_expr_Econdition_correct:
@@ -552,52 +700,20 @@ Lemma transl_expr_Econdition_correct:
t = t1 ** t2 ->
transl_expr_correct sp le e m (Econdition a b c) t m2 v2.
Proof.
- intros; red; intros. simpl in TE; monadInv TE. intro EQ1; clear TE.
-
- assert (MWF1: map_wf map s1).
- apply map_wf_incr with s. eauto with rtlg. assumption.
- generalize (H0 _ _ _ _ _ _ _ MWF1 EQ1 ME).
- intros [rs1 [EX1 [ME1 OTHER1]]].
- destruct v1.
-
- assert (MWF0: map_wf map s0). eauto with rtlg.
- assert (TRG0: target_reg_ok s0 map b rd).
- inversion TRG. apply target_reg_other; eauto with rtlg.
- generalize (H2 _ _ _ _ _ _ _ MWF0 EQ0 ME1 TRG0).
- intros [rs2 [EX2 [ME2 [RES2 OTHER2]]]].
- exists rs2.
-(* Exec *)
- split. eapply exec_trans. eexact EX1.
- apply exec_instrs_incr with s1. eauto with rtlg.
- eexact EX2. auto.
-(* Match-env *)
- split. assumption.
-(* Result value *)
- split. assumption.
-(* Other regs *)
- intros. transitivity (rs1#r).
- apply OTHER2; auto. eauto with rtlg.
- apply OTHER1; auto. apply reg_valid_incr with s.
- apply state_incr_trans with s0; eauto with rtlg. assumption.
-
- assert (TRGc: target_reg_ok s map c rd).
- inversion TRG. apply target_reg_other; auto.
- generalize (H2 _ _ _ _ _ _ _ MWF EQ ME1 TRGc).
- intros [rs2 [EX2 [ME2 [RES2 OTHER2]]]].
+ intros; red; intros; inv TE.
+ exploit H0; eauto. intros [rs1 [EX1 [ME1 OTHER1]]].
+ assert (tr_expr code map pr (if v1 then b else c) (if v1 then ntrue else nfalse) nd rd).
+ destruct v1; auto.
+ exploit H2; eauto. intros [rs2 [EX2 [ME2 [RES2 OTHER2]]]].
exists rs2.
(* Exec *)
- split. eapply exec_trans. eexact EX1.
- apply exec_instrs_incr with s0. eauto with rtlg.
- eexact EX2. auto.
+ split. eapply star_trans. eexact EX1. eexact EX2. auto.
(* Match-env *)
split. assumption.
(* Result value *)
split. assumption.
(* Other regs *)
- intros. transitivity (rs1#r).
- apply OTHER2; auto. eauto with rtlg.
- apply OTHER1; auto. apply reg_valid_incr with s.
- apply state_incr_trans2 with s0 s1; eauto with rtlg. assumption.
+ intros. transitivity (rs1#r); auto.
Qed.
Lemma transl_expr_Elet_correct:
@@ -611,47 +727,25 @@ Lemma transl_expr_Elet_correct:
t = t1 ** t2 ->
transl_expr_correct sp le e m (Elet a b) t m2 v2.
Proof.
- intros; red; intros.
- simpl in TE; monadInv TE. intro EQ1.
- assert (MWF1: map_wf map s1). eauto with rtlg.
- assert (TRG1: target_reg_ok s1 map a r).
- eapply target_reg_other; eauto with rtlg.
- generalize (H0 _ _ _ _ _ _ _ MWF1 EQ1 ME TRG1).
- intros [rs1 [EX1 [ME1 [RES1 OTHER1]]]].
- assert (MWF2: map_wf (add_letvar map r) s0).
- apply add_letvar_wf; eauto with rtlg.
- assert (ME2: match_env (add_letvar map r) e (v1 :: le) rs1).
- apply match_env_letvar; assumption.
- assert (TRG2: target_reg_ok s0 (add_letvar map r) b rd).
- inversion TRG. apply target_reg_other.
- unfold reg_in_map, add_letvar; simpl. red; intro.
- elim H10; intro. apply H4. left. assumption.
- elim H11; intro. apply valid_fresh_absurd with rd s.
- assumption. rewrite <- H12. eauto with rtlg.
- apply H4. right. assumption.
- eauto with rtlg.
- generalize (H2 _ _ _ _ _ _ _ MWF2 EQ0 ME2 TRG2).
+ intros; red; intros; inv TE.
+ exploit H0; eauto. intros [rs1 [EX1 [ME1 [RES1 OTHER1]]]].
+ assert (map_wf (add_letvar map r)).
+ eapply add_letvar_wf; eauto.
+ exploit H2; eauto. eapply match_env_bind_letvar; eauto.
intros [rs2 [EX2 [ME3 [RES2 OTHER2]]]].
exists rs2.
(* Exec *)
- split. eapply exec_trans. eexact EX1.
- apply exec_instrs_incr with s1. eauto with rtlg. eexact EX2. auto.
+ split. eapply star_trans. eexact EX1. eexact EX2. auto.
(* Match-env *)
- split. apply mk_match_env. exact (me_vars _ _ _ _ ME3).
- generalize (me_letvars _ _ _ _ ME3).
- unfold add_letvar; simpl. intro X; injection X; auto.
+ split. eapply match_env_unbind_letvar; eauto.
(* Result *)
split. assumption.
(* Other regs *)
intros. transitivity (rs1#r0).
- apply OTHER2. eauto with rtlg.
- elim H5; intro. left.
+ apply OTHER2. elim H4; intro; auto.
unfold reg_in_map, add_letvar; simpl.
- unfold reg_in_map in H6; tauto.
- tauto.
- apply OTHER1. eauto with rtlg.
- right. red; intro. apply valid_fresh_absurd with r0 s.
- assumption. rewrite H6. eauto with rtlg.
+ unfold reg_in_map in H5; tauto.
+ auto.
Qed.
Lemma transl_expr_Eletvar_correct:
@@ -660,35 +754,22 @@ Lemma transl_expr_Eletvar_correct:
nth_error le n = Some v ->
transl_expr_correct sp le e m (Eletvar n) E0 m v.
Proof.
- intros; red; intros.
- simpl in TE; monadInv TE. intro EQ1.
- generalize EQ. unfold find_letvar.
- caseEq (nth_error (map_letvars map) n).
- intros r0 NE; monadSimpl. subst s0; subst r0.
- generalize (add_move_correct _ _ sp _ _ _ _ rs m EQ1).
- intros [rs1 [EX1 [RES1 OTHER1]]].
+ intros; red; intros; inv TE.
+ exploit tr_move_correct; eauto. intros [rs1 [EX1 [RES1 OTHER1]]].
exists rs1.
(* Exec *)
- split. exact EX1.
+ split. eexact EX1.
(* Match-env *)
- split. inversion TRG.
- assert (r = rd). congruence.
- subst r. apply match_env_exten with rs.
- intros. case (Reg.eq r rd); intro. subst r; auto. auto. auto.
- apply match_env_invariant with rs. auto.
- intros. apply OTHER1. red;intro;subst r1. contradiction.
+ split. apply match_env_invariant with rs. auto.
+ intros. destruct H2 as [A | [B C]].
+ subst r. destruct (Reg.eq r0 rd). subst r0; auto. auto.
+ apply OTHER1. intuition congruence.
(* Result *)
- split. rewrite RES1.
- generalize H. rewrite <- (me_letvars _ _ _ _ ME).
- change positive with reg.
- rewrite list_map_nth. rewrite NE. simpl. congruence.
+ split. rewrite RES1. eapply match_env_find_letvar; eauto.
(* Other regs *)
- intros. inversion TRG.
- assert (r = rd). congruence. subst r.
- case (Reg.eq r0 rd); intro. subst r0; auto. auto.
- apply OTHER1. red; intro; subst r0. tauto.
-
- intro; monadSimpl.
+ intros. destruct H2 as [A | [B C]].
+ subst r. destruct (Reg.eq r0 rd). subst r0; auto. auto.
+ apply OTHER1. intuition congruence.
Qed.
Lemma transl_expr_Ealloc_correct:
@@ -700,47 +781,35 @@ Lemma transl_expr_Ealloc_correct:
Mem.alloc m1 0 (Int.signed n) = (m2, b) ->
transl_expr_correct sp le e m (Ealloc a) t m2 (Vptr b Int.zero).
Proof.
- intros until b; intros EE TEC ALLOC; red; intros.
- simpl in TE. monadInv TE. intro EQ1.
- assert (TRG': target_reg_ok s1 map a r); eauto with rtlg.
- assert (MWF': map_wf map s1). eauto with rtlg.
- generalize (TEC _ _ _ _ _ _ _ MWF' EQ1 ME TRG').
- intros [rs1 [EX1 [ME1 [RR1 RO1]]]].
+ intros; red; intros; inv TE.
+ exploit H0; eauto. intros [rs1 [EX1 [ME1 [RR1 RO1]]]].
exists (rs1#rd <- (Vptr b Int.zero)).
(* Exec *)
- split. eapply exec_trans. eexact EX1.
- apply exec_instrs_incr with s1. eauto with rtlg.
- apply exec_one; eapply exec_Ialloc. eauto with rtlg.
+ split. eapply star_right. eexact EX1.
+ eapply exec_Ialloc. eauto with rtlg.
eexact RR1. assumption. traceEq.
(* Match-env *)
- split. inversion TRG. eauto with rtlg.
+ split. eauto with rtlg.
(* Result *)
split. apply Regmap.gss.
(* Other regs *)
- intros. rewrite Regmap.gso.
- apply RO1. eauto with rtlg.
- case (Reg.eq r0 r); intro.
- subst r0. left. elim (alloc_reg_fresh_or_in_map _ _ _ _ _ MWF EQ); intro.
- auto. byContradiction; eauto with rtlg.
- right; assumption.
- elim H0; intro. red; intro. subst r0. inversion TRG. contradiction.
- auto.
+ intros. rewrite Regmap.gso. auto. intuition congruence.
Qed.
Lemma transl_condition_CEtrue_correct:
forall (sp: val) (le : letenv) (e : env) (m : mem),
transl_condition_correct sp le e m CEtrue E0 m true.
Proof.
- intros; red; intros. simpl in TE; monadInv TE. subst ns.
- exists rs. split. apply exec_refl. split. auto. auto.
+ intros; red; intros; inv TE.
+ exists rs. split. apply star_refl. split. auto. auto.
Qed.
Lemma transl_condition_CEfalse_correct:
forall (sp: val) (le : letenv) (e : env) (m : mem),
transl_condition_correct sp le e m CEfalse E0 m false.
Proof.
- intros; red; intros. simpl in TE; monadInv TE. subst ns.
- exists rs. split. apply exec_refl. split. auto. auto.
+ intros; red; intros; inv TE.
+ exists rs. split. apply star_refl. split. auto. auto.
Qed.
Lemma transl_condition_CEcond_correct:
@@ -749,33 +818,24 @@ Lemma transl_condition_CEcond_correct:
(m1 : mem) (vl : list val) (b : bool),
eval_exprlist ge sp le e m al t1 m1 vl ->
transl_exprlist_correct sp le e m al t1 m1 vl ->
- eval_condition cond vl = Some b ->
+ eval_condition cond vl m1 = Some b ->
transl_condition_correct sp le e m (CEcond cond al) t1 m1 b.
Proof.
- intros; red; intros. simpl in TE; monadInv TE. intro EQ1; clear TE.
- assert (MWF1: map_wf map s1). eauto with rtlg.
- assert (TRG: target_regs_ok s1 map al l). eauto with rtlg.
- generalize (H0 _ _ _ _ _ _ _ MWF1 EQ1 ME TRG).
- intros [rs1 [EX1 [ME1 [RES1 OTHER1]]]].
+ intros; red; intros; inv TE.
+ exploit H0; eauto. intros [rs1 [EX1 [ME1 [RES1 OTHER1]]]].
exists rs1.
(* Exec *)
- split. eapply exec_trans. eexact EX1.
- apply exec_instrs_incr with s1. eauto with rtlg.
- apply exec_one.
+ split. eapply star_right. eexact EX1.
destruct b.
- eapply exec_Icond_true. eauto with rtlg.
+ eapply exec_Icond_true; eauto.
rewrite RES1. assumption.
- eapply exec_Icond_false. eauto with rtlg.
+ eapply exec_Icond_false; eauto.
rewrite RES1. assumption.
traceEq.
(* Match-env *)
split. assumption.
(* Regs *)
- intros. apply OTHER1. eauto with rtlg.
- case (In_dec Reg.eq r l); intro.
- elim (alloc_regs_fresh_or_in_map _ _ _ _ _ MWF EQ r i); intro.
- tauto. byContradiction; eauto with rtlg.
- tauto.
+ auto.
Qed.
Lemma transl_condition_CEcondition_correct:
@@ -789,47 +849,31 @@ Lemma transl_condition_CEcondition_correct:
t = t1 ** t2 ->
transl_condition_correct sp le e m (CEcondition a b c) t m2 vb2.
Proof.
- intros; red; intros. simpl in TE; monadInv TE. intro EQ1; clear TE.
- assert (MWF1: map_wf map s1). eauto with rtlg.
- generalize (H0 _ _ _ _ _ _ _ MWF1 EQ1 ME).
- intros [rs1 [EX1 [ME1 OTHER1]]].
- destruct vb1.
-
- assert (MWF0: map_wf map s0). eauto with rtlg.
- generalize (H2 _ _ _ _ _ _ _ MWF0 EQ0 ME1).
- intros [rs2 [EX2 [ME2 OTHER2]]].
- exists rs2.
- split. eapply exec_trans. eexact EX1.
- apply exec_instrs_incr with s1. eauto with rtlg.
- eexact EX2. auto.
- split. assumption.
- intros. transitivity (rs1#r).
- apply OTHER2; eauto with rtlg.
- apply OTHER1; eauto with rtlg.
-
- generalize (H2 _ _ _ _ _ _ _ MWF EQ ME1).
- intros [rs2 [EX2 [ME2 OTHER2]]].
+ intros; red; intros; inv TE.
+ exploit H0; eauto. intros [rs1 [EX1 [ME1 OTHER1]]].
+ assert (tr_condition code map pr (if vb1 then b else c)
+ (if vb1 then ntrue' else nfalse') ntrue nfalse).
+ destruct vb1; auto.
+ exploit H2; eauto. intros [rs2 [EX2 [ME2 OTHER2]]].
exists rs2.
- split. eapply exec_trans. eexact EX1.
- apply exec_instrs_incr with s0. eauto with rtlg.
- eexact EX2. auto.
- split. assumption.
- intros. transitivity (rs1#r).
- apply OTHER2; eauto with rtlg.
- apply OTHER1; eauto with rtlg.
+(* Execution *)
+ split. eapply star_trans. eexact EX1. eexact EX2. auto.
+(* Match-env *)
+ split. auto.
+(* Regs *)
+ intros. transitivity (rs1#r); auto.
Qed.
Lemma transl_exprlist_Enil_correct:
forall (sp: val) (le : letenv) (e : env) (m : mem),
transl_exprlist_correct sp le e m Enil E0 m nil.
Proof.
- intros; red; intros.
- generalize TE. simpl. destruct rl; monadSimpl.
- subst s'; subst ns. exists rs.
- split. apply exec_refl.
+ intros; red; intros; inv TE.
+ exists rs.
+ split. apply star_refl.
split. assumption.
split. reflexivity.
- intros. reflexivity.
+ auto.
Qed.
Lemma transl_exprlist_Econs_correct:
@@ -843,93 +887,90 @@ Lemma transl_exprlist_Econs_correct:
t = t1 ** t2 ->
transl_exprlist_correct sp le e m (Econs a bl) t m2 (v :: vl).
Proof.
- intros. red. intros.
- inversion TRG.
- rewrite <- H10 in TE. simpl in TE. monadInv TE. intro EQ1.
- assert (MWF1: map_wf map s1); eauto with rtlg.
- assert (TRG1: target_reg_ok s1 map a r); eauto with rtlg.
- generalize (H0 _ _ _ _ _ _ _ MWF1 EQ1 ME TRG1).
- intros [rs1 [EX1 [ME1 [RES1 OTHER1]]]].
- generalize (H2 _ _ _ _ _ _ _ MWF EQ ME1 H11).
- intros [rs2 [EX2 [ME2 [RES2 OTHER2]]]].
+ intros; red; intros; inv TE.
+ exploit H0; eauto. intros [rs1 [EX1 [ME1 [RES1 OTHER1]]]].
+ exploit H2; eauto. intros [rs2 [EX2 [ME2 [RES2 OTHER2]]]].
exists rs2.
(* Exec *)
- split. eapply exec_trans. eexact EX1.
- apply exec_instrs_incr with s1. eauto with rtlg.
- eexact EX2. auto.
+ split. eapply star_trans. eexact EX1. eexact EX2. auto.
(* Match-env *)
split. assumption.
(* Results *)
- split. simpl. rewrite RES2. rewrite OTHER2. rewrite RES1.
- reflexivity.
- eauto with rtlg.
- eauto with rtlg.
+ split. simpl. rewrite RES2. rewrite OTHER2. rewrite RES1. auto.
+ simpl; tauto.
(* Other regs *)
- simpl. intros.
- transitivity (rs1#r0).
- apply OTHER2; auto. tauto.
- apply OTHER1; auto. eauto with rtlg.
- elim H13; intro. left; assumption. right; apply sym_not_equal; tauto.
+ intros. transitivity (rs1#r).
+ apply OTHER2; auto. simpl; tauto.
+ apply OTHER1; auto.
Qed.
Lemma transl_funcall_internal_correct:
- forall (m : mem) (f : Cminor.function)
+ forall (m : mem) (f : CminorSel.function)
(vargs : list val) (m1 : mem) (sp : block) (e : env) (t : trace)
- (e2 : env) (m2 : mem) (out : outcome) (vres : val),
+ (e2 : env) (m2 : mem) (out: outcome) (vres : val),
Mem.alloc m 0 (fn_stackspace f) = (m1, sp) ->
- set_locals (fn_vars f) (set_params vargs (Cminor.fn_params f)) = e ->
+ set_locals (fn_vars f) (set_params vargs (CminorSel.fn_params f)) = e ->
exec_stmt ge (Vptr sp Int.zero) e m1 (fn_body f) t e2 m2 out ->
transl_stmt_correct (Vptr sp Int.zero) e m1 (fn_body f) t e2 m2 out ->
- outcome_result_value out f.(Cminor.fn_sig).(sig_res) vres ->
- transl_function_correct m (Internal f)
- vargs t (Mem.free m2 sp) vres.
+ outcome_result_value out f.(CminorSel.fn_sig).(sig_res) vres ->
+ transl_function_correct m (Internal f) vargs t
+ (outcome_free_mem out m2 sp) vres.
Proof.
intros; red; intros.
- generalize TE. unfold transl_fundef, transl_function; simpl.
- caseEq (transl_fun f init_state).
- intros; discriminate.
- intros ns s. unfold transl_fun. monadSimpl.
- subst ns. intros EQ4. injection EQ4; intro TF; clear EQ4.
- subst s4.
-
- pose (rs := init_regs vargs x).
- assert (ME: match_env y0 e nil rs).
+ generalize TE; simpl. caseEq (transl_function f); simpl. 2: congruence.
+ intros tfi EQ1 EQ2. injection EQ2; clear EQ2; intro EQ2.
+ assert (TR: tr_function f tfi). apply transl_function_charact; auto.
+ rewrite <- EQ2. inversion TR. subst f0.
+
+ pose (rs := init_regs vargs rparams).
+ assert (ME: match_env map2 e nil rs).
rewrite <- H0. unfold rs.
- eapply match_init_env_init_reg; eauto.
+ eapply match_init_env_init_reg; eauto.
+
+ assert (MWF: map_wf map2).
+ assert (map_valid init_mapping init_state) by apply init_mapping_valid.
+ exploit (add_vars_valid (CminorSel.fn_params f)); eauto. intros [A B].
+ eapply add_vars_wf; eauto. eapply add_vars_wf; eauto. apply init_mapping_wf.
+
+ exploit H2; eauto. intros [rs' [st [OUT [EX ME']]]].
+
+ eapply star_left.
+ eapply exec_function_internal; eauto. simpl.
+ inversion OUT; clear OUT; subst out st; simpl in H3; simpl.
+
+ (* Out_normal *)
+ unfold ret_reg in H6. destruct (sig_res (CminorSel.fn_sig f)). contradiction.
+ subst vres orret.
+ eapply star_right. unfold rs in EX. eexact EX.
+ change Vundef with (regmap_optget None Vundef rs').
+ apply exec_Ireturn. auto. reflexivity.
+
+ (* Out_exit *)
+ contradiction.
+
+ (* Out_return None *)
+ subst orret.
+ unfold ret_reg in H8. destruct (sig_res (CminorSel.fn_sig f)). contradiction.
+ subst vres.
+ eapply star_right. unfold rs in EX. eexact EX.
+ change Vundef with (regmap_optget None Vundef rs').
+ apply exec_Ireturn. auto.
+ reflexivity.
- assert (OUT: outcome_node out n nil n n).
- red. generalize H3. unfold outcome_result_value.
- destruct out; contradiction || auto.
-
- assert (MWF1: map_wf y0 s1).
- eapply add_vars_wf. eexact EQ0.
- eapply add_vars_wf. eexact EQ.
- apply init_mapping_wf.
-
- assert (MWF: map_wf y0 s3).
- apply map_wf_incr with s1. apply state_incr_trans with s2; eauto with rtlg.
- assumption.
-
- set (rr := ret_reg (Cminor.fn_sig f) r) in *.
- assert (RRG: return_reg_ok s3 y0 rr).
- apply return_reg_ok_incr with s2. eauto with rtlg.
- unfold rr; apply new_reg_return_ok with s1; assumption.
-
- generalize (H2 _ _ _ _ _ _ _ _ _ rs MWF EQ3 ME OUT RRG).
- intros [rs1 [EX1 [ME1 MR1]]].
-
- rewrite <- TF. apply exec_funct_internal with m1 n rs1 rr; simpl.
- assumption.
- exact EX1.
- apply instr_at_incr with s3.
- eauto with rtlg. discriminate. eauto with rtlg.
- generalize MR1. unfold match_return_outcome.
- generalize H3. unfold outcome_result_value.
- unfold rr, ret_reg; destruct (sig_res (Cminor.fn_sig f)).
- unfold regmap_optget. destruct out; try contradiction.
- destruct o; try contradiction. intros; congruence.
- unfold regmap_optget. destruct out; contradiction||auto.
- destruct o; contradiction||auto.
+ (* Out_return Some *)
+ subst orret.
+ unfold ret_reg in H8. unfold ret_reg in H9.
+ destruct (sig_res (CminorSel.fn_sig f)). inversion H9.
+ subst vres.
+ eapply star_right. unfold rs in EX. eexact EX.
+ replace v with (regmap_optget (Some rret) Vundef rs').
+ apply exec_Ireturn. auto.
+ simpl. congruence.
+ reflexivity.
+ contradiction.
+
+ (* a tail call *)
+ subst v. rewrite E0_right. auto. traceEq.
Qed.
Lemma transl_funcall_external_correct:
@@ -939,17 +980,27 @@ Lemma transl_funcall_external_correct:
Proof.
intros; red; intros. unfold transl_function in TE; simpl in TE.
inversion TE; subst tf.
- apply exec_funct_external. auto.
+ apply star_one. apply exec_function_external. auto.
Qed.
Lemma transl_stmt_Sskip_correct:
forall (sp: val) (e : env) (m : mem),
transl_stmt_correct sp e m Sskip E0 e m Out_normal.
Proof.
- intros; red; intros. simpl in TE. monadInv TE.
- subst s'; subst ns.
- simpl in OUT. subst ncont.
- exists rs. simpl. intuition. apply exec_refl.
+ intros; red; intros; inv TE.
+ exists rs; econstructor.
+ split. constructor.
+ split. apply star_refl.
+ auto.
+Qed.
+
+Remark state_for_outcome_stop:
+ forall ncont1 ncont2 nexits nret rret cs code sp rs m out st,
+ state_for_outcome ncont1 nexits nret rret cs code sp rs m out st ->
+ out <> Out_normal ->
+ state_for_outcome ncont2 nexits nret rret cs code sp rs m out st.
+Proof.
+ intros. inv H; congruence || econstructor; eauto.
Qed.
Lemma transl_stmt_Sseq_continue_correct:
@@ -963,22 +1014,13 @@ Lemma transl_stmt_Sseq_continue_correct:
t = t1 ** t2 ->
transl_stmt_correct sp e m (Sseq s1 s2) t e2 m2 out.
Proof.
- intros; red; intros. simpl in TE; monadInv TE. intro EQ0.
- assert (MWF1: map_wf map s0). eauto with rtlg.
- assert (OUTs: outcome_node Out_normal n nexits nret n).
- simpl. auto.
- assert (RRG1: return_reg_ok s0 map rret). eauto with rtlg.
- generalize (H0 _ _ _ _ _ _ _ _ _ _ MWF1 EQ0 ME OUTs RRG1).
- intros [rs1 [EX1 [ME1 MR1]]].
- generalize (H2 _ _ _ _ _ _ _ _ _ _ MWF EQ ME1 OUT RRG).
- intros [rs2 [EX2 [ME2 MR2]]].
- exists rs2.
-(* Exec *)
- split. eapply exec_trans. eexact EX1.
- apply exec_instrs_incr with s0. eauto with rtlg.
- eexact EX2. auto.
-(* Match-env + return *)
- tauto.
+ intros; red; intros; inv TE.
+ exploit H0; eauto. intros [rs1 [st1 [OUT1 [EX1 ME1]]]]. inv OUT1.
+ exploit H2; eauto. intros [rs2 [st2 [OUT2 [EX2 ME2]]]].
+ exists rs2; exists st2.
+ split. eauto.
+ split. eapply star_trans; eauto.
+ auto.
Qed.
Lemma transl_stmt_Sseq_stop_correct:
@@ -989,13 +1031,11 @@ Lemma transl_stmt_Sseq_stop_correct:
out <> Out_normal ->
transl_stmt_correct sp e m (Sseq s1 s2) t e1 m1 out.
Proof.
- intros; red; intros.
- simpl in TE; monadInv TE. intro EQ0; clear TE.
- assert (MWF1: map_wf map s0). eauto with rtlg.
- assert (OUTs: outcome_node out n nexits nret nd).
- destruct out; simpl; auto. tauto.
- assert (RRG1: return_reg_ok s0 map rret). eauto with rtlg.
- exact (H0 _ _ _ _ _ _ _ _ _ _ MWF1 EQ0 ME OUTs RRG1).
+ intros; red; intros; inv TE.
+ exploit H0; eauto. intros [rs1 [st1 [OUT1 [EX1 ME1]]]].
+ exists rs1; exists st1.
+ split. eapply state_for_outcome_stop; eauto.
+ auto.
Qed.
Lemma transl_stmt_Sexpr_correct:
@@ -1005,14 +1045,11 @@ Lemma transl_stmt_Sexpr_correct:
transl_expr_correct sp nil e m a t m1 v ->
transl_stmt_correct sp e m (Sexpr a) t e m1 Out_normal.
Proof.
- intros; red; intros.
- simpl in OUT. subst nd.
- unfold transl_stmt in TE. monadInv TE. intro EQ1.
- assert (MWF0: map_wf map s0). eauto with rtlg.
- assert (TRG: target_reg_ok s0 map a r). eauto with rtlg.
- generalize (H0 _ _ _ _ _ _ _ MWF0 EQ1 ME TRG).
- intros [rs1 [EX1 [ME1 [RES1 OTHER1]]]].
- exists rs1; simpl; tauto.
+ intros; red; intros; inv TE.
+ exploit H0; eauto. intros [rs1 [EX1 [ME1 [RES1 OTHER1]]]].
+ exists rs1; econstructor.
+ split. constructor.
+ eauto.
Qed.
Lemma transl_stmt_Sassign_correct:
@@ -1022,26 +1059,17 @@ Lemma transl_stmt_Sassign_correct:
transl_expr_correct sp nil e m a t m1 v ->
transl_stmt_correct sp e m (Sassign id a) t (PTree.set id v e) m1 Out_normal.
Proof.
- intros; red; intros.
- simpl in TE. monadInv TE. intro EQ2.
- assert (MWF0: map_wf map s2).
- apply map_wf_incr with s. eauto 6 with rtlg. auto.
- assert (TRGa: target_reg_ok s2 map a r0). eauto 6 with rtlg.
- generalize (H0 _ _ _ _ _ _ _ MWF0 EQ2 ME TRGa).
- intros [rs1 [EX1 [ME1 [RES1 OTHER1]]]].
- generalize (add_move_correct _ _ sp _ _ _ _ rs1 m1 EQ1).
- intros [rs2 [EX2 [RES2 OTHER2]]].
- exists rs2.
-(* Exec *)
- split. inversion OUT; subst. eapply exec_trans. eexact EX1.
- apply exec_instrs_incr with s2. eauto with rtlg.
- eexact EX2. traceEq.
-(* Match-env *)
- split.
- apply match_env_update_var with rs1 r s s0; auto.
- congruence.
-(* Outcome *)
- simpl; auto.
+ intros; red; intros; inv TE.
+ exploit H0; eauto. intros [rs1 [EX1 [ME1 [RES1 OTHER1]]]].
+ exploit tr_move_correct; eauto. intros [rs2 [EX2 [RES2 OTHER2]]].
+ exists rs2; econstructor.
+ split. constructor.
+ split. eapply star_trans. eexact EX1. eexact EX2. traceEq.
+ apply match_env_invariant with (rs1#rv <- v).
+ apply match_env_update_var; auto.
+ intros. rewrite Regmap.gsspec. destruct (peq r rv).
+ subst r. congruence.
+ auto.
Qed.
Lemma transl_stmt_Sifthenelse_correct:
@@ -1055,45 +1083,15 @@ Lemma transl_stmt_Sifthenelse_correct:
t = t1 ** t2 ->
transl_stmt_correct sp e m (Sifthenelse a s1 s2) t e2 m2 out.
Proof.
- intros; red; intros until rs; intro MWF.
- simpl. case (more_likely a s1 s2); monadSimpl; intro EQ2; intros.
- assert (MWF1: map_wf map s3). eauto with rtlg.
- generalize (H0 _ _ _ _ _ _ rs MWF1 EQ2 ME).
- intros [rs1 [EX1 [ME1 OTHER1]]].
- destruct v1.
- assert (MWF0: map_wf map s0). eauto with rtlg.
- assert (RRG0: return_reg_ok s0 map rret). eauto with rtlg.
- generalize (H2 _ _ _ _ _ _ _ _ _ _ MWF0 EQ0 ME1 OUT RRG0).
- intros [rs2 [EX2 [ME2 MRE2]]].
- exists rs2. split.
- eapply exec_trans. eexact EX1. apply exec_instrs_incr with s3.
- eauto with rtlg. eexact EX2. auto.
- tauto.
- generalize (H2 _ _ _ _ _ _ _ _ _ _ MWF EQ ME1 OUT RRG).
- intros [rs2 [EX2 [ME2 MRE2]]].
- exists rs2. split.
- eapply exec_trans. eexact EX1. apply exec_instrs_incr with s0.
- eauto with rtlg. eexact EX2. auto.
- tauto.
-
- assert (MWF1: map_wf map s3). eauto with rtlg.
- generalize (H0 _ _ _ _ _ _ rs MWF1 EQ2 ME).
- intros [rs1 [EX1 [ME1 OTHER1]]].
- destruct v1.
- generalize (H2 _ _ _ _ _ _ _ _ _ _ MWF EQ ME1 OUT RRG).
- intros [rs2 [EX2 [ME2 MRE2]]].
- exists rs2. split.
- eapply exec_trans. eexact EX1. apply exec_instrs_incr with s0.
- eauto with rtlg. eexact EX2. auto.
- tauto.
- assert (MWF0: map_wf map s0). eauto with rtlg.
- assert (RRG0: return_reg_ok s0 map rret). eauto with rtlg.
- generalize (H2 _ _ _ _ _ _ _ _ _ _ MWF0 EQ0 ME1 OUT RRG0).
- intros [rs2 [EX2 [ME2 MRE2]]].
- exists rs2. split.
- eapply exec_trans. eexact EX1. apply exec_instrs_incr with s3.
- eauto with rtlg. eexact EX2. auto.
- tauto.
+ intros; red; intros; inv TE.
+ exploit H0; eauto. intros [rs1 [EX1 [ME1 OTHER1]]].
+ assert (tr_stmt code map (if v1 then s1 else s2) (if v1 then ntrue else nfalse) ncont nexits nret rret).
+ destruct v1; auto.
+ exploit H2; eauto. intros [rs2 [st2 [OUT2 [EX2 ME2]]]].
+ exists rs2; exists st2.
+ split. eauto.
+ split. eapply star_trans. eexact EX1. eexact EX2. auto.
+ auto.
Qed.
Lemma transl_stmt_Sloop_loop_correct:
@@ -1107,34 +1105,15 @@ Lemma transl_stmt_Sloop_loop_correct:
t = t1 ** t2 ->
transl_stmt_correct sp e m (Sloop sl) t e2 m2 out.
Proof.
- intros; red; intros.
- generalize TE. simpl. monadSimpl. subst s2; subst n0. intros.
- assert (MWF0: map_wf map s0). apply map_wf_incr with s.
- eapply reserve_instr_incr; eauto.
- assumption.
- assert (OUT0: outcome_node Out_normal n nexits nret n).
- unfold outcome_node. auto.
- assert (RRG0: return_reg_ok s0 map rret).
- apply return_reg_ok_incr with s.
- eapply reserve_instr_incr; eauto.
- assumption.
- generalize (H0 _ _ _ _ _ _ _ _ _ _ MWF0 EQ0 ME OUT0 RRG0).
- intros [rs1 [EX1 [ME1 MR1]]].
- generalize (H2 _ _ _ _ _ _ _ _ _ _ MWF TE ME1 OUT RRG).
- intros [rs2 [EX2 [ME2 MR2]]].
- exists rs2.
- split. eapply exec_trans.
- apply exec_instrs_extends with s1.
- eapply update_instr_extends.
- eexact EQ. eauto with rtlg. eexact EQ1. eexact EX1.
- apply exec_trans with E0 ns rs1 m1 t2.
- apply exec_one. apply exec_Inop.
- generalize EQ1. unfold update_instr.
- case (plt n (st_nextnode s1)); intro; monadSimpl.
- rewrite <- H5. simpl. apply PTree.gss.
- exact EX2.
- reflexivity. traceEq.
- tauto.
+ intros; red; intros; inversion TE. subst.
+ exploit H0; eauto. intros [rs1 [st1 [OUT1 [EX1 ME1]]]]. inv OUT1.
+ exploit H2; eauto. intros [rs2 [st2 [OUT2 [EX2 ME2]]]].
+ exists rs2; exists st2.
+ split. eauto.
+ split. eapply star_trans. eexact EX1.
+ eapply star_left. apply exec_Inop; eauto. eexact EX2.
+ reflexivity. traceEq.
+ auto.
Qed.
Lemma transl_stmt_Sloop_stop_correct:
@@ -1145,25 +1124,12 @@ Lemma transl_stmt_Sloop_stop_correct:
out <> Out_normal ->
transl_stmt_correct sp e m (Sloop sl) t e1 m1 out.
Proof.
- intros; red; intros.
- simpl in TE. monadInv TE. subst s2; subst n0.
- assert (MWF0: map_wf map s0). apply map_wf_incr with s.
- eapply reserve_instr_incr; eauto. assumption.
- assert (OUT0: outcome_node out n nexits nret nd).
- generalize OUT. unfold outcome_node.
- destruct out; auto. elim H1; auto.
- assert (RRG0: return_reg_ok s0 map rret).
- apply return_reg_ok_incr with s.
- eapply reserve_instr_incr; eauto.
- assumption.
- generalize (H0 _ _ _ _ _ _ _ _ _ _ MWF0 EQ0 ME OUT0 RRG0).
- intros [rs1 [EX1 [ME1 MR1]]].
- exists rs1. split.
- apply exec_instrs_extends with s1.
- eapply update_instr_extends.
- eexact EQ. eauto with rtlg. eexact EQ1. eexact EX1.
- tauto.
-Qed.
+ intros; red; intros; inv TE.
+ exploit H0; eauto. intros [rs1 [st1 [OUT1 [EX1 ME1]]]].
+ exists rs1; exists st1.
+ split. eapply state_for_outcome_stop; eauto.
+ auto.
+Qed.
Lemma transl_stmt_Sblock_correct:
forall (sp: val) (e : env) (m : mem) (sl : stmt) (t: trace)
@@ -1172,65 +1138,59 @@ Lemma transl_stmt_Sblock_correct:
transl_stmt_correct sp e m sl t e1 m1 out ->
transl_stmt_correct sp e m (Sblock sl) t e1 m1 (outcome_block out).
Proof.
- intros; red; intros. simpl in TE.
- assert (OUT': outcome_node out ncont (ncont :: nexits) nret nd).
- generalize OUT. unfold outcome_node, outcome_block.
- destruct out.
+ intros; red; intros; inv TE.
+ exploit H0; eauto. intros [rs1 [st1 [OUT1 [EX1 ME1]]]].
+ exists rs1; exists st1.
+ split. inv OUT1; simpl; try (econstructor; eauto).
+ destruct n; simpl in H1.
+ inv H1. constructor.
+ constructor. auto.
auto.
- destruct n. simpl. intro; unfold value; congruence.
- simpl. auto.
- auto.
- generalize (H0 _ _ _ _ _ _ _ _ _ _ MWF TE ME OUT' RRG).
- intros [rs1 [EX1 [ME1 MR1]]].
- exists rs1.
- split. assumption.
- split. assumption.
- generalize MR1. unfold match_return_outcome, outcome_block.
- destruct out; auto.
- destruct n; simpl; auto.
-Qed.
-
-Lemma transl_exit_correct:
- forall nexits ex s nd s',
- transl_exit nexits ex s = OK nd s' ->
- nth_error nexits ex = Some nd.
-Proof.
- intros until s'. unfold transl_exit.
- case (nth_error nexits ex); intros; simplify_eq H; congruence.
Qed.
Lemma transl_stmt_Sexit_correct:
forall (sp: val) (e : env) (m : mem) (n : nat),
transl_stmt_correct sp e m (Sexit n) E0 e m (Out_exit n).
Proof.
- intros; red; intros.
- simpl in TE. simpl in OUT.
- generalize (transl_exit_correct _ _ _ _ _ TE); intro.
- assert (ns = nd). congruence. subst ns.
- exists rs. simpl. intuition. apply exec_refl.
+ intros; red; intros; inv TE.
+ exists rs; econstructor.
+ split. econstructor; eauto.
+ split. apply star_refl.
+ auto.
Qed.
Lemma transl_switch_correct:
- forall sp rs m r i nexits nd default cases s ns s',
- transl_switch r nexits cases default s = OK ns s' ->
- nth_error nexits (switch_target i default cases) = Some nd ->
+ forall cs sp rs m i code r nexits t ns,
+ tr_switch code r nexits t ns ->
rs#r = Vint i ->
- exec_instrs tge s'.(st_code) sp ns rs m E0 nd rs m.
+ exists nd,
+ star step tge (State cs code sp ns rs m) E0 (State cs code sp nd rs m) /\
+ nth_error nexits (comptree_match i t) = Some nd.
Proof.
- induction cases; simpl; intros.
- generalize (transl_exit_correct _ _ _ _ _ H). intros.
- assert (ns = nd). congruence. subst ns. apply exec_refl.
- destruct a as [key1 exit1]. monadInv H. clear H. intro EQ1.
- caseEq (Int.eq i key1); intro IEQ; rewrite IEQ in H0.
- (* i = key1 *)
- apply exec_trans with E0 n0 rs m E0. apply exec_one.
- eapply exec_Icond_true. eauto with rtlg. simpl. rewrite H1. congruence.
- generalize (transl_exit_correct _ _ _ _ _ EQ0); intro.
- assert (n0 = nd). congruence. subst n0. apply exec_refl. traceEq.
- (* i <> key1 *)
- apply exec_trans with E0 n rs m E0. apply exec_one.
- eapply exec_Icond_false. eauto with rtlg. simpl. rewrite H1. congruence.
- apply exec_instrs_incr with s0; eauto with rtlg. traceEq.
+ induction 1; intros; simpl.
+ exists n. split. apply star_refl. auto.
+
+ caseEq (Int.eq i key); intros.
+ exists nfound; split.
+ apply star_one. eapply exec_Icond_true; eauto.
+ simpl. rewrite H2. congruence. auto.
+ exploit IHtr_switch; eauto. intros [nd [EX MATCH]].
+ exists nd; split.
+ eapply star_step. eapply exec_Icond_false; eauto.
+ simpl. rewrite H2. congruence. eexact EX. traceEq.
+ auto.
+
+ caseEq (Int.ltu i key); intros.
+ exploit IHtr_switch1; eauto. intros [nd [EX MATCH]].
+ exists nd; split.
+ eapply star_step. eapply exec_Icond_true; eauto.
+ simpl. rewrite H2. congruence. eexact EX. traceEq.
+ auto.
+ exploit IHtr_switch2; eauto. intros [nd [EX MATCH]].
+ exists nd; split.
+ eapply star_step. eapply exec_Icond_false; eauto.
+ simpl. rewrite H2. congruence. eexact EX. traceEq.
+ auto.
Qed.
Lemma transl_stmt_Sswitch_correct:
@@ -1242,32 +1202,25 @@ Lemma transl_stmt_Sswitch_correct:
transl_stmt_correct sp e m (Sswitch a cases default) t1 e m1
(Out_exit (switch_target n default cases)).
Proof.
- intros; red; intros. monadInv TE. clear TE; intros EQ1.
- simpl in OUT.
- assert (state_incr s s1). eauto with rtlg.
-
- red in H0.
- assert (MWF1: map_wf map s1). eauto with rtlg.
- assert (TRG1: target_reg_ok s1 map a r). eauto with rtlg.
- destruct (H0 _ _ _ _ _ _ _ MWF1 EQ1 ME TRG1)
- as [rs' [EXEC1 [ME1 [RES1 OTHER1]]]].
- simpl. exists rs'.
- (* execution *)
- split. eapply exec_trans. eexact EXEC1.
- apply exec_instrs_incr with s1. eauto with rtlg.
- eapply transl_switch_correct; eauto. traceEq.
- (* match_env & match_reg *)
- tauto.
+ intros; red; intros; inv TE.
+ exploit H0; eauto. intros [rs1 [EX1 [ME1 [RES1 OTHER1]]]].
+ exploit transl_switch_correct; eauto. intros [nd [EX2 MO2]].
+ exists rs1; econstructor.
+ split. econstructor.
+ rewrite (validate_switch_correct _ _ _ H4 n). eauto.
+ split. eapply star_trans. eexact EX1. eexact EX2. traceEq.
+ auto.
Qed.
Lemma transl_stmt_Sreturn_none_correct:
forall (sp: val) (e : env) (m : mem),
transl_stmt_correct sp e m (Sreturn None) E0 e m (Out_return None).
Proof.
- intros; red; intros. generalize TE. simpl.
- destruct rret; monadSimpl.
- simpl in OUT. subst ns; subst nret.
- exists rs. intuition. apply exec_refl.
+ intros; red; intros; inv TE.
+ exists rs; econstructor.
+ split. constructor. auto.
+ split. apply star_refl.
+ auto.
Qed.
Lemma transl_stmt_Sreturn_some_correct:
@@ -1277,33 +1230,59 @@ Lemma transl_stmt_Sreturn_some_correct:
transl_expr_correct sp nil e m a t m1 v ->
transl_stmt_correct sp e m (Sreturn (Some a)) t e m1 (Out_return (Some v)).
Proof.
- intros; red; intros. generalize TE; simpl.
- destruct rret. intro EQ.
- assert (TRG: target_reg_ok s map a r).
- inversion RRG. apply target_reg_other; auto.
- generalize (H0 _ _ _ _ _ _ _ MWF EQ ME TRG).
- intros [rs1 [EX1 [ME1 [RES1 OTHER1]]]].
- simpl in OUT. subst nd. exists rs1. tauto.
-
- monadSimpl.
+ intros; red; intros; inv TE.
+ exploit H0; eauto. intros [rs1 [EX1 [ME1 [RES1 OTHER1]]]].
+ exists rs1; econstructor.
+ split. econstructor. reflexivity. auto.
+ eauto.
+Qed.
+
+Lemma transl_stmt_Stailcall_correct:
+ forall (sp : block) (e : env) (m : mem) (sig : signature) (a : expr)
+ (bl : exprlist) (t t1 : trace) (m1 : mem) (t2 : trace) (m2 : mem)
+ (t3 : trace) (m3 : mem) (vf : val) (vargs : list val) (vres : val)
+ (f : CminorSel.fundef),
+ eval_expr ge (Vptr sp Int.zero) nil e m a t1 m1 vf ->
+ transl_expr_correct (Vptr sp Int.zero) nil e m a t1 m1 vf ->
+ eval_exprlist ge (Vptr sp Int.zero) nil e m1 bl t2 m2 vargs ->
+ transl_exprlist_correct (Vptr sp Int.zero) nil e m1 bl t2 m2 vargs ->
+ Genv.find_funct ge vf = Some f ->
+ CminorSel.funsig f = sig ->
+ eval_funcall ge (free m2 sp) f vargs t3 m3 vres ->
+ transl_function_correct (free m2 sp) f vargs t3 m3 vres ->
+ t = t1 ** t2 ** t3 ->
+ transl_stmt_correct (Vptr sp Int.zero) e m (Stailcall sig a bl)
+ t e m3 (Out_tailcall_return vres).
+Proof.
+ intros; red; intros; inv TE.
+ exploit H0; eauto. intros [rs1 [EX1 [ME1 [RES1 OTHER1]]]].
+ exploit H2; eauto. intros [rs2 [EX2 [ME2 [RES2 OTHER2]]]].
+ exploit functions_translated; eauto. intros [tf [TFIND TF]].
+ exploit H6; eauto. intro EXF.
+ exists rs2; econstructor.
+ split. constructor.
+ split.
+ eapply star_trans. eexact EX1.
+ eapply star_trans. eexact EX2.
+ eapply star_step.
+ eapply exec_Itailcall; eauto.
+ simpl. rewrite OTHER2. rewrite RES1. eauto. simpl; tauto.
+ eapply sig_transl_function; eauto.
+ rewrite RES2. eexact EXF.
+ reflexivity. reflexivity. traceEq.
+ auto.
Qed.
(** The correctness of the translation then follows by application
- of the mutual induction principle for Cminor evaluation derivations
+ of the mutual induction principle for CminorSel evaluation derivations
to the lemmas above. *)
-Scheme eval_expr_ind_5 := Minimality for eval_expr Sort Prop
- with eval_condexpr_ind_5 := Minimality for eval_condexpr Sort Prop
- with eval_exprlist_ind_5 := Minimality for eval_exprlist Sort Prop
- with eval_funcall_ind_5 := Minimality for eval_funcall Sort Prop
- with exec_stmt_ind_5 := Minimality for exec_stmt Sort Prop.
-
Theorem transl_function_correctness:
forall m f vargs t m' vres,
eval_funcall ge m f vargs t m' vres ->
transl_function_correct m f vargs t m' vres.
Proof
- (eval_funcall_ind_5 ge
+ (eval_funcall_ind5 ge
transl_expr_correct
transl_condition_correct
transl_exprlist_correct
@@ -1339,26 +1318,35 @@ Proof
transl_stmt_Sexit_correct
transl_stmt_Sswitch_correct
transl_stmt_Sreturn_none_correct
- transl_stmt_Sreturn_some_correct).
+ transl_stmt_Sreturn_some_correct
+ transl_stmt_Stailcall_correct).
+
+Require Import Smallstep.
+
+(** The correctness of the translation follows: if the original CminorSel
+ program executes with trace [t] and exit code [r], then the generated
+ RTL program terminates with the same trace and exit code. *)
Theorem transl_program_correct:
- forall (t: trace) (r: val),
- Cminor.exec_program prog t r ->
- RTL.exec_program tprog t r.
+ forall (t: trace) (r: int),
+ CminorSel.exec_program prog t (Vint r) ->
+ RTL.exec_program tprog (Terminates t r).
Proof.
intros t r [b [f [m [SYMB [FUNC [SIG EVAL]]]]]].
generalize (function_ptr_translated _ _ FUNC).
intros [tf [TFIND TRANSLF]].
- red; exists b; exists tf; exists m.
- split. rewrite symbols_preserved.
- replace (prog_main tprog) with (prog_main prog).
- assumption.
+ exploit transl_function_correctness; eauto. intro EX.
+ econstructor.
+ econstructor.
+ rewrite symbols_preserved.
+ replace (prog_main tprog) with (prog_main prog). eauto.
symmetry; apply transform_partial_program_main with transl_fundef.
exact TRANSL.
- split. exact TFIND.
- split. generalize (sig_transl_function _ _ TRANSLF). congruence.
+ eexact TFIND.
+ generalize (sig_transl_function _ _ TRANSLF). congruence.
unfold fundef; rewrite (Genv.init_mem_transf_partial transl_fundef prog TRANSL).
- exact (transl_function_correctness _ _ _ _ _ _ EVAL _ TRANSLF).
+ eexact EX.
+ constructor.
Qed.
End CORRECTNESS.
diff --git a/backend/RTLgenproof1.v b/backend/RTLgenproof1.v
deleted file mode 100644
index 8e12e79..0000000
--- a/backend/RTLgenproof1.v
+++ /dev/null
@@ -1,1367 +0,0 @@
-(** Correctness proof for RTL generation: auxiliary results. *)
-
-Require Import Coqlib.
-Require Import Maps.
-Require Import AST.
-Require Import Integers.
-Require Import Values.
-Require Import Events.
-Require Import Mem.
-Require Import Globalenvs.
-Require Import Op.
-Require Import Registers.
-Require Import Cminor.
-Require Import RTL.
-Require Import RTLgen.
-
-(** * Reasoning about monadic computations *)
-
-(** The tactics below simplify hypotheses of the form [f ... = OK x s]
- where [f] is a monadic computation. For instance, the hypothesis
- [(do x <- a; b) s = OK y s'] will generate the additional witnesses
- [x], [s1] and the additional hypotheses
- [a s = OK x s1] and [b x s1 = OK y s'], reflecting the fact that
- both monadic computations [a] and [b] succeeded.
-*)
-
-Ltac monadSimpl1 :=
- match goal with
- | [ |- (bind ?F ?G ?S = OK ?X ?S') -> _ ] =>
- unfold bind at 1;
- generalize (refl_equal (F S));
- pattern (F S) at -1 in |- *;
- case (F S);
- [ intro; intro; discriminate
- | (let s := fresh "s" in
- (let EQ := fresh "EQ" in
- (intro; intros s EQ;
- try monadSimpl1))) ]
- | [ |- (bind2 ?F ?G ?S = OK ?X ?S') -> _ ] =>
- unfold bind2 at 1; unfold bind at 1;
- generalize (refl_equal (F S));
- pattern (F S) at -1 in |- *;
- case (F S);
- [ intro; intro; discriminate
- | let xy := fresh "xy" in
- (let x := fresh "x" in
- (let y := fresh "y" in
- (let s := fresh "s" in
- (let EQ := fresh "EQ" in
- (intros xy s EQ; destruct xy as [x y]; simpl;
- try monadSimpl1))))) ]
- | [ |- (error _ _ = OK _ _) -> _ ] =>
- unfold error; monadSimpl1
- | [ |- (ret _ _ = OK _ _) -> _ ] =>
- unfold ret; monadSimpl1
- | [ |- (Error _ = OK _ _) -> _ ] =>
- intro; discriminate
- | [ |- (OK _ _ = OK _ _) -> _ ] =>
- let h := fresh "H" in
- (intro h; injection h; intro; intro; clear h)
- end.
-
-Ltac monadSimpl :=
- match goal with
- | [ |- (bind ?F ?G ?S = OK ?X ?S') -> _ ] => monadSimpl1
- | [ |- (bind2 ?F ?G ?S = OK ?X ?S') -> _ ] => monadSimpl1
- | [ |- (error _ _ = OK _ _) -> _ ] => monadSimpl1
- | [ |- (ret _ _ = OK _ _) -> _ ] => monadSimpl1
- | [ |- (Error _ = OK _ _) -> _ ] => monadSimpl1
- | [ |- (OK _ _ = OK _ _) -> _ ] => monadSimpl1
- | [ |- (?F _ _ _ _ _ _ _ = OK _ _) -> _ ] => unfold F; monadSimpl1
- | [ |- (?F _ _ _ _ _ _ = OK _ _) -> _ ] => unfold F; monadSimpl1
- | [ |- (?F _ _ _ _ _ = OK _ _) -> _ ] => unfold F; monadSimpl1
- | [ |- (?F _ _ _ _ = OK _ _) -> _ ] => unfold F; monadSimpl1
- | [ |- (?F _ _ _ = OK _ _) -> _ ] => unfold F; monadSimpl1
- | [ |- (?F _ _ = OK _ _) -> _ ] => unfold F; monadSimpl1
- | [ |- (?F _ = OK _ _) -> _ ] => unfold F; monadSimpl1
- end.
-
-Ltac monadInv H :=
- generalize H; monadSimpl.
-
-(** * Monotonicity properties of the state *)
-
-(** Operations over the global state satisfy a crucial monotonicity property:
- nodes are only added to the CFG, but never removed nor their instructions
- changed; similarly, fresh nodes and fresh registers are only consumed,
- but never reused. This property is captured by the following predicate
- over states, which we show is a partial order. *)
-
-Inductive state_incr: state -> state -> Prop :=
- state_incr_intro:
- forall (s1 s2: state),
- Ple s1.(st_nextnode) s2.(st_nextnode) ->
- Ple s1.(st_nextreg) s2.(st_nextreg) ->
- (forall pc, Plt pc s1.(st_nextnode) -> s2.(st_code)!pc = s1.(st_code)!pc) ->
- state_incr s1 s2.
-
-Lemma instr_at_incr:
- forall s1 s2 n i,
- s1.(st_code)!n = i -> i <> None -> state_incr s1 s2 ->
- s2.(st_code)!n = i.
-Proof.
- intros. inversion H1.
- rewrite <- H. apply H4. elim (st_wf s1 n); intro.
- assumption. elim H0. congruence.
-Qed.
-
-Lemma state_incr_refl:
- forall s, state_incr s s.
-Proof.
- intros. apply state_incr_intro.
- apply Ple_refl. apply Ple_refl. intros; auto.
-Qed.
-Hint Resolve state_incr_refl: rtlg.
-
-Lemma state_incr_trans:
- forall s1 s2 s3, state_incr s1 s2 -> state_incr s2 s3 -> state_incr s1 s3.
-Proof.
- intros. inversion H. inversion H0. apply state_incr_intro.
- apply Ple_trans with (st_nextnode s2); assumption.
- apply Ple_trans with (st_nextreg s2); assumption.
- intros. transitivity (s2.(st_code)!pc).
- apply H8. apply Plt_Ple_trans with s1.(st_nextnode); auto.
- apply H3; auto.
-Qed.
-Hint Resolve state_incr_trans: rtlg.
-
-Lemma state_incr_trans2:
- forall s1 s2 s3 s4,
- state_incr s1 s2 -> state_incr s2 s3 -> state_incr s3 s4 ->
- state_incr s1 s4.
-Proof.
- intros; eauto with rtlg.
-Qed.
-
-Lemma state_incr_trans3:
- forall s1 s2 s3 s4 s5,
- state_incr s1 s2 -> state_incr s2 s3 -> state_incr s3 s4 -> state_incr s4 s5 ->
- state_incr s1 s5.
-Proof.
- intros; eauto with rtlg.
-Qed.
-
-Lemma state_incr_trans4:
- forall s1 s2 s3 s4 s5 s6,
- state_incr s1 s2 -> state_incr s2 s3 -> state_incr s3 s4 ->
- state_incr s4 s5 -> state_incr s5 s6 ->
- state_incr s1 s6.
-Proof.
- intros; eauto with rtlg.
-Qed.
-
-Lemma state_incr_trans5:
- forall s1 s2 s3 s4 s5 s6 s7,
- state_incr s1 s2 -> state_incr s2 s3 -> state_incr s3 s4 ->
- state_incr s4 s5 -> state_incr s5 s6 -> state_incr s6 s7 ->
- state_incr s1 s7.
-Proof.
- intros; eauto 6 with rtlg.
-Qed.
-
-Lemma state_incr_trans6:
- forall s1 s2 s3 s4 s5 s6 s7 s8,
- state_incr s1 s2 -> state_incr s2 s3 -> state_incr s3 s4 ->
- state_incr s4 s5 -> state_incr s5 s6 -> state_incr s6 s7 ->
- state_incr s7 s8 -> state_incr s1 s8.
-Proof.
- intros; eauto 7 with rtlg.
-Qed.
-
-(** The following relation between two states is a weaker version of
- [state_incr]. It permits changing the contents at an already reserved
- graph node, but only from [None] to [Some i]. *)
-
-Definition state_extends (s1 s2: state): Prop :=
- forall pc,
- s1.(st_code)!pc = None \/ s2.(st_code)!pc = s1.(st_code)!pc.
-
-Lemma state_incr_extends:
- forall s1 s2,
- state_incr s1 s2 -> state_extends s1 s2.
-Proof.
- unfold state_extends; intros. inversion H.
- case (plt pc s1.(st_nextnode)); intro.
- right; apply H2; auto.
- left. elim (s1.(st_wf) pc); intro.
- elim (n H5). auto.
-Qed.
-Hint Resolve state_incr_extends.
-
-(** A crucial property of states is the following: if an RTL execution
- is possible (does not get stuck) in the CFG of a given state [s1]
- the same execution is possible and leads to the same results in
- the CFG of any state [s2] that extends [s1] in the sense of the
- [state_extends] predicate. *)
-
-Section EXEC_INSTR_EXTENDS.
-
-Variable s1 s2: state.
-Hypothesis EXT: state_extends s1 s2.
-
-Lemma exec_instr_not_halt:
- forall ge c sp pc rs m t pc' rs' m',
- exec_instr ge c sp pc rs m t pc' rs' m' -> c!pc <> None.
-Proof.
- induction 1; rewrite H; discriminate.
-Qed.
-
-Lemma exec_instr_in_s2:
- forall ge sp pc rs m t pc' rs' m',
- exec_instr ge s1.(st_code) sp pc rs m t pc' rs' m' ->
- s2.(st_code)!pc = s1.(st_code)!pc.
-Proof.
- intros.
- elim (EXT pc); intro.
- elim (exec_instr_not_halt _ _ _ _ _ _ _ _ _ _ H H0).
- assumption.
-Qed.
-
-Lemma exec_instr_extends_rec:
- forall ge c sp pc rs m t pc' rs' m',
- exec_instr ge c sp pc rs m t pc' rs' m' ->
- forall c', c!pc = c'!pc ->
- exec_instr ge c' sp pc rs m t pc' rs' m'.
-Proof.
- induction 1; intros.
- apply exec_Inop. congruence.
- apply exec_Iop with op args. congruence. auto.
- apply exec_Iload with chunk addr args a. congruence. auto. auto.
- apply exec_Istore with chunk addr args src a.
- congruence. auto. auto.
- apply exec_Icall with sig ros args f; auto. congruence.
- apply exec_Ialloc with arg sz; auto. congruence.
- apply exec_Icond_true with cond args ifnot; auto. congruence.
- apply exec_Icond_false with cond args ifso; auto. congruence.
-Qed.
-
-Lemma exec_instr_extends:
- forall ge sp pc rs m t pc' rs' m',
- exec_instr ge s1.(st_code) sp pc rs m t pc' rs' m' ->
- exec_instr ge s2.(st_code) sp pc rs m t pc' rs' m'.
-Proof.
- intros.
- apply exec_instr_extends_rec with (st_code s1).
- assumption.
- symmetry. eapply exec_instr_in_s2. eexact H.
-Qed.
-
-Lemma exec_instrs_extends_rec:
- forall ge c sp pc rs m t pc' rs' m',
- exec_instrs ge c sp pc rs m t pc' rs' m' ->
- c = s1.(st_code) ->
- exec_instrs ge s2.(st_code) sp pc rs m t pc' rs' m'.
-Proof.
- induction 1; intros.
- apply exec_refl.
- apply exec_one. apply exec_instr_extends; auto. rewrite <- H0; auto.
- apply exec_trans with t1 pc2 rs2 m2 t2; auto.
-Qed.
-
-Lemma exec_instrs_extends:
- forall ge sp pc rs m t pc' rs' m',
- exec_instrs ge s1.(st_code) sp pc rs m t pc' rs' m' ->
- exec_instrs ge s2.(st_code) sp pc rs m t pc' rs' m'.
-Proof.
- intros.
- apply exec_instrs_extends_rec with (st_code s1); auto.
-Qed.
-
-End EXEC_INSTR_EXTENDS.
-
-(** Since [state_incr s1 s2] implies [state_extends s1 s2], we also have
- that any RTL execution possible in the CFG of [s1] is also possible
- in the CFG of [s2], provided that [state_incr s1 s2].
- In particular, any RTL execution that is possible in a partially
- constructed CFG remains possible in the final CFG obtained at
- the end of the translation of the current function. *)
-
-Section EXEC_INSTR_INCR.
-
-Variable s1 s2: state.
-Hypothesis INCR: state_incr s1 s2.
-
-Lemma exec_instr_incr:
- forall ge sp pc rs m t pc' rs' m',
- exec_instr ge s1.(st_code) sp pc rs m t pc' rs' m' ->
- exec_instr ge s2.(st_code) sp pc rs m t pc' rs' m'.
-Proof.
- intros.
- apply exec_instr_extends with s1.
- apply state_incr_extends; auto.
- auto.
-Qed.
-
-Lemma exec_instrs_incr:
- forall ge sp pc rs m t pc' rs' m',
- exec_instrs ge s1.(st_code) sp pc rs m t pc' rs' m' ->
- exec_instrs ge s2.(st_code) sp pc rs m t pc' rs' m'.
-Proof.
- intros.
- apply exec_instrs_extends with s1.
- apply state_incr_extends; auto.
- auto.
-Qed.
-
-End EXEC_INSTR_INCR.
-
-(** * Validity and freshness of registers *)
-
-(** An RTL pseudo-register is valid in a given state if it was created
- earlier, that is, it is less than the next fresh register of the state.
- Otherwise, the pseudo-register is said to be fresh. *)
-
-Definition reg_valid (r: reg) (s: state) : Prop :=
- Plt r s.(st_nextreg).
-
-Definition reg_fresh (r: reg) (s: state) : Prop :=
- ~(Plt r s.(st_nextreg)).
-
-Lemma valid_fresh_absurd:
- forall r s, reg_valid r s -> reg_fresh r s -> False.
-Proof.
- intros r s. unfold reg_valid, reg_fresh; case r; tauto.
-Qed.
-Hint Resolve valid_fresh_absurd: rtlg.
-
-Lemma valid_fresh_different:
- forall r1 r2 s, reg_valid r1 s -> reg_fresh r2 s -> r1 <> r2.
-Proof.
- unfold not; intros. subst r2. eauto with rtlg.
-Qed.
-Hint Resolve valid_fresh_different: rtlg.
-
-Lemma reg_valid_incr:
- forall r s1 s2, state_incr s1 s2 -> reg_valid r s1 -> reg_valid r s2.
-Proof.
- intros r s1 s2 INCR.
- inversion INCR.
- unfold reg_valid. intros; apply Plt_Ple_trans with (st_nextreg s1); auto.
-Qed.
-Hint Resolve reg_valid_incr: rtlg.
-
-Lemma reg_fresh_decr:
- forall r s1 s2, state_incr s1 s2 -> reg_fresh r s2 -> reg_fresh r s1.
-Proof.
- intros r s1 s2 INCR. inversion INCR.
- unfold reg_fresh; unfold not; intros.
- apply H4. apply Plt_Ple_trans with (st_nextreg s1); auto.
-Qed.
-Hint Resolve reg_fresh_decr: rtlg.
-
-(** * Well-formedness of compilation environments *)
-
-(** A compilation environment (mapping) is well-formed in a given state if
- the following properties hold:
-- The registers associated with Cminor local variables and let-bound variables
- are valid in the state.
-- Two distinct Cminor local variables are mapped to distinct pseudo-registers.
-- A Cminor local variable and a let-bound variable are mapped to
- distinct pseudo-registers.
-*)
-
-Record map_wf (m: mapping) (s: state) : Prop :=
- mk_map_wf {
- map_wf_var_valid:
- (forall id r, m.(map_vars)!id = Some r -> reg_valid r s);
- map_wf_letvar_valid:
- (forall r, In r m.(map_letvars) -> reg_valid r s);
- map_wf_inj:
- (forall id1 id2 r,
- m.(map_vars)!id1 = Some r -> m.(map_vars)!id2 = Some r -> id1 = id2);
- map_wf_disj:
- (forall id r,
- m.(map_vars)!id = Some r -> In r m.(map_letvars) -> False)
- }.
-Hint Resolve map_wf_var_valid
- map_wf_letvar_valid
- map_wf_inj map_wf_disj: rtlg.
-
-Lemma map_wf_incr:
- forall s1 s2 m,
- state_incr s1 s2 -> map_wf m s1 -> map_wf m s2.
-Proof.
- intros. apply mk_map_wf; intros; eauto with rtlg.
-Qed.
-Hint Resolve map_wf_incr: rtlg.
-
-(** A register is ``in'' a mapping if it is associated with a Cminor
- local or let-bound variable. *)
-
-Definition reg_in_map (m: mapping) (r: reg) : Prop :=
- (exists id, m.(map_vars)!id = Some r) \/ In r m.(map_letvars).
-
-Lemma reg_in_map_valid:
- forall m s r,
- map_wf m s -> reg_in_map m r -> reg_valid r s.
-Proof.
- intros. elim H0.
- intros [id EQ]. eauto with rtlg.
- intro IN. eauto with rtlg.
-Qed.
-Hint Resolve reg_in_map_valid: rtlg.
-
-(** * Properties of basic operations over the state *)
-
-(** Properties of [add_instr]. *)
-
-Lemma add_instr_incr:
- forall s1 s2 i n,
- add_instr i s1 = OK n s2 -> state_incr s1 s2.
-Proof.
- intros until n; monadSimpl.
- subst s2; apply state_incr_intro; simpl.
- apply Ple_succ.
- apply Ple_refl.
- intros. apply PTree.gso; apply Plt_ne; auto.
-Qed.
-Hint Resolve add_instr_incr: rtlg.
-
-Lemma add_instr_at:
- forall s1 s2 i n,
- add_instr i s1 = OK n s2 -> s2.(st_code)!n = Some i.
-Proof.
- intros until n; monadSimpl.
- subst n; subst s2; simpl. apply PTree.gss.
-Qed.
-Hint Resolve add_instr_at.
-
-(** Properties of [reserve_instr] and [update_instr]. *)
-
-Lemma reserve_instr_incr:
- forall s1 s2 n,
- reserve_instr s1 = OK n s2 -> state_incr s1 s2.
-Proof.
- intros until n; monadSimpl. subst s2.
- apply state_incr_intro; simpl.
- apply Ple_succ.
- apply Ple_refl.
- auto.
-Qed.
-
-Lemma update_instr_incr:
- forall s1 s2 s3 s4 i n t,
- reserve_instr s1 = OK n s2 ->
- state_incr s2 s3 ->
- update_instr n i s3 = OK t s4 ->
- state_incr s1 s4.
-Proof.
- intros.
- monadInv H.
- generalize H1; unfold update_instr.
- case (plt n (st_nextnode s3)); intro.
- monadSimpl. inversion H0.
- subst s4; apply state_incr_intro; simpl.
- apply Plt_Ple. apply Plt_Ple_trans with (st_nextnode s2).
- subst s2; simpl; apply Plt_succ. assumption.
- rewrite <- H3 in H7; simpl in H7. assumption.
- intros. rewrite PTree.gso.
- rewrite <- H3 in H8; simpl in H8. apply H8.
- apply Plt_trans_succ; assumption.
- subst n; apply Plt_ne; assumption.
- intros; discriminate.
-Qed.
-
-Lemma update_instr_extends:
- forall s1 s2 s3 s4 i n t,
- reserve_instr s1 = OK n s2 ->
- state_incr s2 s3 ->
- update_instr n i s3 = OK t s4 ->
- state_extends s3 s4.
-Proof.
- intros.
- monadInv H.
- red; intros.
- case (peq pc n); intro.
- subst pc. left. inversion H0. rewrite H6.
- rewrite <- H3; simpl.
- elim (s1.(st_wf) n); intro.
- rewrite <- H4 in H9. elim (Plt_strict _ H9).
- auto.
- rewrite <- H4. rewrite <- H3; simpl. apply Plt_succ.
- generalize H1; unfold update_instr.
- case (plt n s3.(st_nextnode)); intro; monadSimpl.
- right; rewrite <- H5; simpl. apply PTree.gso; auto.
-Qed.
-
-(** Properties of [new_reg]. *)
-
-Lemma new_reg_incr:
- forall s1 s2 r, new_reg s1 = OK r s2 -> state_incr s1 s2.
-Proof.
- intros until r. monadSimpl.
- subst s2; apply state_incr_intro; simpl.
- apply Ple_refl. apply Ple_succ. auto.
-Qed.
-Hint Resolve new_reg_incr: rtlg.
-
-Lemma new_reg_valid:
- forall s1 s2 r,
- new_reg s1 = OK r s2 -> reg_valid r s2.
-Proof.
- intros until r. monadSimpl. subst s2; subst r.
- unfold reg_valid; unfold reg_valid; simpl.
- apply Plt_succ.
-Qed.
-Hint Resolve new_reg_valid: rtlg.
-
-Lemma new_reg_fresh:
- forall s1 s2 r,
- new_reg s1 = OK r s2 -> reg_fresh r s1.
-Proof.
- intros until r. monadSimpl. subst s2; subst r.
- unfold reg_fresh; simpl.
- exact (Plt_strict _).
-Qed.
-Hint Resolve new_reg_fresh: rtlg.
-
-Lemma new_reg_not_in_map:
- forall s1 s2 m r,
- new_reg s1 = OK r s2 -> map_wf m s1 -> ~(reg_in_map m r).
-Proof.
- unfold not; intros; eauto with rtlg.
-Qed.
-Hint Resolve new_reg_not_in_map: rtlg.
-
-(** * Properties of operations over compilation environments *)
-
-Lemma init_mapping_wf:
- forall s, map_wf init_mapping s.
-Proof.
- intro. unfold init_mapping; apply mk_map_wf; simpl; intros.
- rewrite PTree.gempty in H; discriminate.
- contradiction.
- rewrite PTree.gempty in H; discriminate.
- tauto.
-Qed.
-
-(** Properties of [find_var]. *)
-
-Lemma find_var_incr:
- forall s1 s2 map name r,
- find_var map name s1 = OK r s2 -> state_incr s1 s2.
-Proof.
- intros until r. unfold find_var.
- case (map_vars map)!name.
- intro; monadSimpl. subst s2; auto with rtlg.
- monadSimpl.
-Qed.
-Hint Resolve find_var_incr: rtlg.
-
-Lemma find_var_in_map:
- forall s1 s2 map name r,
- find_var map name s1 = OK r s2 -> map_wf map s1 -> reg_in_map map r.
-Proof.
- intros until r. unfold find_var; caseEq (map.(map_vars)!name).
- intros r0 eq. monadSimpl; intros. subst r0.
- left. exists name; auto.
- intro; monadSimpl.
-Qed.
-Hint Resolve find_var_in_map: rtlg.
-
-Lemma find_var_valid:
- forall s1 s2 map name r,
- find_var map name s1 = OK r s2 -> map_wf map s1 -> reg_valid r s1.
-Proof.
- eauto with rtlg.
-Qed.
-Hint Resolve find_var_valid: rtlg.
-
-
-(** Properties of [find_letvar]. *)
-
-Lemma find_letvar_incr:
- forall s1 s2 map idx r,
- find_letvar map idx s1 = OK r s2 -> state_incr s1 s2.
-Proof.
- intros until r. unfold find_letvar.
- case (nth_error (map_letvars map) idx).
- intro; monadSimpl. subst s2; auto with rtlg.
- monadSimpl.
-Qed.
-Hint Resolve find_letvar_incr: rtlg.
-
-Lemma find_letvar_in_map:
- forall s1 s2 map idx r,
- find_letvar map idx s1 = OK r s2 -> map_wf map s1 -> reg_in_map map r.
-Proof.
- intros until r. unfold find_letvar.
- caseEq (nth_error (map_letvars map) idx).
- intros r0 EQ; monadSimpl. intros. right.
- subst r0; apply nth_error_in with idx; auto.
- intro; monadSimpl.
-Qed.
-Hint Resolve find_letvar_in_map: rtlg.
-
-Lemma find_letvar_valid:
- forall s1 s2 map idx r,
- find_letvar map idx s1 = OK r s2 -> map_wf map s1 -> reg_valid r s1.
-Proof.
- eauto with rtlg.
-Qed.
-Hint Resolve find_letvar_valid: rtlg.
-
-(** Properties of [add_var]. *)
-
-Lemma add_var_valid:
- forall s1 s2 map1 map2 name r,
- add_var map1 name s1 = OK (r, map2) s2 -> reg_valid r s2.
-Proof.
- intros until r. monadSimpl. intro. subst r0; subst s.
- eauto with rtlg.
-Qed.
-
-Lemma add_var_incr:
- forall s1 s2 map name rm,
- add_var map name s1 = OK rm s2 -> state_incr s1 s2.
-Proof.
- intros until rm; monadSimpl. subst s2. eauto with rtlg.
-Qed.
-Hint Resolve add_var_incr: rtlg.
-
-Lemma add_var_wf:
- forall s1 s2 map name r map',
- add_var map name s1 = OK (r,map') s2 -> map_wf map s1 -> map_wf map' s2.
-Proof.
- intros until map'; monadSimpl; intros.
- subst r0; subst s; subst map'; apply mk_map_wf; simpl.
-
- intros id r'. rewrite PTree.gsspec.
- case (peq id name); intros.
- injection H; intros; subst r'. eauto with rtlg.
- eauto with rtlg.
- eauto with rtlg.
-
- intros id1 id2 r'.
- repeat (rewrite PTree.gsspec).
- case (peq id1 name); case (peq id2 name); intros.
- congruence.
- rewrite <- H in H0. byContradiction; eauto with rtlg.
- rewrite <- H0 in H. byContradiction; eauto with rtlg.
- eauto with rtlg.
-
- intros id r'. case (peq id name); intro.
- subst id. rewrite PTree.gss. intro E; injection E; intro; subst r'.
- intro; eauto with rtlg.
-
- rewrite PTree.gso; auto. eauto with rtlg.
-Qed.
-Hint Resolve add_var_wf: rtlg.
-
-Lemma add_var_find:
- forall s1 s2 map name r map',
- add_var map name s1 = OK (r,map') s2 -> map'.(map_vars)!name = Some r.
-Proof.
- intros until map'.
- monadSimpl.
- intro; subst r0.
- subst map'; simpl in |- *.
- apply PTree.gss.
-Qed.
-
-Lemma add_vars_incr:
- forall names s1 s2 map r,
- add_vars map names s1 = OK r s2 -> state_incr s1 s2.
-Proof.
- induction names; simpl.
- intros until r; monadSimpl; intros. subst s2; eauto with rtlg.
- intros until r; monadSimpl; intros.
- subst s0; eauto with rtlg.
-Qed.
-
-Lemma add_vars_valid:
- forall namel s1 s2 map1 map2 rl,
- add_vars map1 namel s1 = OK (rl, map2) s2 ->
- forall r, In r rl -> reg_valid r s2.
-Proof.
- induction namel; simpl; intros.
- monadInv H. intro. subst rl. elim H0.
- monadInv H. intro EQ1. subst rl; subst s0; subst y0. elim H0.
- intro; subst r. eapply add_var_valid. eexact EQ0.
- intro. apply reg_valid_incr with s. eauto with rtlg.
- eauto.
-Qed.
-
-Lemma add_vars_wf:
- forall names s1 s2 map map' rl,
- add_vars map names s1 = OK (rl,map') s2 ->
- map_wf map s1 -> map_wf map' s2.
-Proof.
- induction names; simpl.
- intros until rl; monadSimpl; intros.
- subst s2; subst map'; assumption.
- intros until rl; monadSimpl; intros. subst y0; subst s0.
- eapply add_var_wf. eexact EQ0.
- eapply IHnames. eexact EQ. auto.
-Qed.
-Hint Resolve add_vars_wf: rtlg.
-
-Lemma add_var_letenv:
- forall map1 i s1 r map2 s2,
- add_var map1 i s1 = OK (r, map2) s2 ->
- map2.(map_letvars) = map1.(map_letvars).
-Proof.
- intros until s2. monadSimpl. intro. subst map2; reflexivity.
-Qed.
-
-(** Properties of [add_letvar]. *)
-
-Lemma add_letvar_wf:
- forall map s r,
- map_wf map s ->
- reg_valid r s ->
- ~(reg_in_map map r) ->
- map_wf (add_letvar map r) s.
-Proof.
- intros. unfold add_letvar; apply mk_map_wf; simpl.
- exact (map_wf_var_valid map s H).
- intros r' [EQ| IN].
- subst r'; assumption.
- eapply map_wf_letvar_valid; eauto.
- exact (map_wf_inj map s H).
- intros. elim H3; intro.
- subst r0. apply H1. left. exists id; auto.
- eapply map_wf_disj; eauto.
-Qed.
-
-(** * Properties of [alloc_reg] and [alloc_regs] *)
-
-Lemma alloc_reg_incr:
- forall a s1 s2 map r,
- alloc_reg map a s1 = OK r s2 -> state_incr s1 s2.
-Proof.
- intros until r. unfold alloc_reg.
- case a; eauto with rtlg.
-Qed.
-Hint Resolve alloc_reg_incr: rtlg.
-
-Lemma alloc_reg_valid:
- forall a s1 s2 map r,
- map_wf map s1 ->
- alloc_reg map a s1 = OK r s2 -> reg_valid r s2.
-Proof.
- intros until r. unfold alloc_reg.
- case a; eauto with rtlg.
-Qed.
-Hint Resolve alloc_reg_valid: rtlg.
-
-Lemma alloc_reg_fresh_or_in_map:
- forall map a s r s',
- map_wf map s ->
- alloc_reg map a s = OK r s' ->
- reg_in_map map r \/ reg_fresh r s.
-Proof.
- intros until s'. unfold alloc_reg.
- destruct a; intros; try (right; eauto with rtlg; fail).
- left; eauto with rtlg.
- left; eauto with rtlg.
-Qed.
-
-Lemma add_vars_letenv:
- forall il map1 s1 rl map2 s2,
- add_vars map1 il s1 = OK (rl, map2) s2 ->
- map2.(map_letvars) = map1.(map_letvars).
-Proof.
- induction il; simpl; intros.
- monadInv H. intro. subst map2; reflexivity.
- monadInv H. intro EQ1. transitivity (map_letvars y).
- subst y0. eapply add_var_letenv; eauto.
- eauto.
-Qed.
-
-(** A register is an adequate target for holding the value of an
- expression if
-- either the register is associated with a Cminor let-bound variable
- or a Cminor local variable;
-- or the register is valid and not associated with any Cminor variable. *)
-
-Inductive target_reg_ok: state -> mapping -> expr -> reg -> Prop :=
- | target_reg_var:
- forall s map id r,
- map.(map_vars)!id = Some r ->
- target_reg_ok s map (Evar id) r
- | target_reg_letvar:
- forall s map idx r,
- nth_error map.(map_letvars) idx = Some r ->
- target_reg_ok s map (Eletvar idx) r
- | target_reg_other:
- forall s map a r,
- ~(reg_in_map map r) ->
- reg_valid r s ->
- target_reg_ok s map a r.
-
-Lemma target_reg_ok_incr:
- forall s1 s2 map e r,
- state_incr s1 s2 ->
- target_reg_ok s1 map e r ->
- target_reg_ok s2 map e r.
-Proof.
- intros. inversion H0.
- apply target_reg_var; auto.
- apply target_reg_letvar; auto.
- apply target_reg_other; eauto with rtlg.
-Qed.
-Hint Resolve target_reg_ok_incr: rtlg.
-
-Lemma target_reg_valid:
- forall s map e r,
- map_wf map s ->
- target_reg_ok s map e r ->
- reg_valid r s.
-Proof.
- intros. inversion H0; eauto with rtlg coqlib.
-Qed.
-Hint Resolve target_reg_valid: rtlg.
-
-Lemma alloc_reg_target_ok:
- forall a s1 s2 map r,
- map_wf map s1 ->
- alloc_reg map a s1 = OK r s2 ->
- target_reg_ok s2 map a r.
-Proof.
- intros until r; intro MWF. unfold alloc_reg.
- case a; intros; try (eapply target_reg_other; eauto with rtlg; fail).
- apply target_reg_var.
- generalize H; unfold find_var.
- case (map_vars map)!i.
- intro. monadSimpl. congruence.
- monadSimpl.
- apply target_reg_letvar.
- generalize H. unfold find_letvar.
- case (nth_error (map_letvars map) n).
- intro; monadSimpl; congruence.
- monadSimpl.
-Qed.
-Hint Resolve alloc_reg_target_ok: rtlg.
-
-Lemma alloc_regs_incr:
- forall al s1 s2 map rl,
- alloc_regs map al s1 = OK rl s2 -> state_incr s1 s2.
-Proof.
- induction al; simpl; intros.
- monadInv H. subst s2. eauto with rtlg.
- monadInv H. subst s2. eauto with rtlg.
-Qed.
-Hint Resolve alloc_regs_incr: rtlg.
-
-Lemma alloc_regs_valid:
- forall al s1 s2 map rl,
- map_wf map s1 ->
- alloc_regs map al s1 = OK rl s2 ->
- forall r, In r rl -> reg_valid r s2.
-Proof.
- induction al; simpl; intros.
- monadInv H0. subst rl. elim H1.
- monadInv H0. subst rl; subst s0.
- elim H1; intro.
- subst r0. eauto with rtlg.
- eauto with rtlg.
-Qed.
-Hint Resolve alloc_regs_valid: rtlg.
-
-Lemma alloc_regs_fresh_or_in_map:
- forall map al s rl s',
- map_wf map s ->
- alloc_regs map al s = OK rl s' ->
- forall r, In r rl -> reg_in_map map r \/ reg_fresh r s.
-Proof.
- induction al; simpl; intros.
- monadInv H0. subst rl. elim H1.
- monadInv H0. subst rl. elim (in_inv H1); intro.
- subst r.
- assert (MWF: map_wf map s0). eauto with rtlg.
- elim (alloc_reg_fresh_or_in_map map e s0 r0 s1 MWF EQ0); intro.
- left; assumption. right; eauto with rtlg.
- eauto with rtlg.
-Qed.
-
-Inductive target_regs_ok: state -> mapping -> exprlist -> list reg -> Prop :=
- | target_regs_nil:
- forall s map,
- target_regs_ok s map Enil nil
- | target_regs_cons:
- forall s map a r al rl,
- reg_in_map map r \/ ~(In r rl) ->
- target_reg_ok s map a r ->
- target_regs_ok s map al rl ->
- target_regs_ok s map (Econs a al) (r :: rl).
-
-Lemma target_regs_ok_incr:
- forall s1 map al rl,
- target_regs_ok s1 map al rl ->
- forall s2,
- state_incr s1 s2 ->
- target_regs_ok s2 map al rl.
-Proof.
- induction 1; intros.
- apply target_regs_nil.
- apply target_regs_cons; eauto with rtlg.
-Qed.
-Hint Resolve target_regs_ok_incr: rtlg.
-
-Lemma target_regs_valid:
- forall s map al rl,
- target_regs_ok s map al rl ->
- map_wf map s ->
- forall r, In r rl -> reg_valid r s.
-Proof.
- induction 1; simpl; intros.
- contradiction.
- elim H3; intro.
- subst r0. eauto with rtlg.
- auto.
-Qed.
-Hint Resolve target_regs_valid: rtlg.
-
-Lemma alloc_regs_target_ok:
- forall al s1 s2 map rl,
- map_wf map s1 ->
- alloc_regs map al s1 = OK rl s2 ->
- target_regs_ok s2 map al rl.
-Proof.
- induction al; simpl; intros.
- monadInv H0. subst rl; apply target_regs_nil.
- monadInv H0. subst s0; subst rl.
- apply target_regs_cons; eauto 6 with rtlg.
- assert (MWF: map_wf map s). eauto with rtlg.
- elim (alloc_reg_fresh_or_in_map map e s r s2 MWF EQ0); intro.
- left; assumption. right; red; intro; eauto with rtlg.
-Qed.
-Hint Resolve alloc_regs_target_ok: rtlg.
-
-(** The following predicate is a variant of [target_reg_ok] used
- to characterize registers that are adequate for holding the return
- value of a function. *)
-
-Inductive return_reg_ok: state -> mapping -> option reg -> Prop :=
- | return_reg_ok_none:
- forall s map,
- return_reg_ok s map None
- | return_reg_ok_some:
- forall s map r,
- ~(reg_in_map map r) -> reg_valid r s ->
- return_reg_ok s map (Some r).
-
-Lemma return_reg_ok_incr:
- forall s1 s2 map or,
- state_incr s1 s2 ->
- return_reg_ok s1 map or ->
- return_reg_ok s2 map or.
-Proof.
- intros. inversion H0; constructor.
- assumption. eauto with rtlg.
-Qed.
-Hint Resolve return_reg_ok_incr: rtlg.
-
-Lemma new_reg_return_ok:
- forall s1 r s2 map sig,
- new_reg s1 = OK r s2 ->
- map_wf map s1 ->
- return_reg_ok s2 map (ret_reg sig r).
-Proof.
- intros. unfold ret_reg. destruct (sig_res sig); constructor.
- eauto with rtlg. eauto with rtlg.
-Qed.
-
-(** * Correspondence between Cminor environments and RTL register sets *)
-
-(** An RTL register environment matches a Cminor local environment and
- let-environment if the value of every local or let-bound variable in
- the Cminor environments is identical to the value of the
- corresponding pseudo-register in the RTL register environment. *)
-
-Record match_env
- (map: mapping) (e: Cminor.env) (le: Cminor.letenv) (rs: regset) : Prop :=
- mk_match_env {
- me_vars:
- (forall id v,
- e!id = Some v -> exists r, map.(map_vars)!id = Some r /\ rs#r = v);
- me_letvars:
- rs##(map.(map_letvars)) = le
- }.
-
-Lemma match_env_find_reg:
- forall map id s1 s2 r e le rs v,
- find_var map id s1 = OK r s2 ->
- match_env map e le rs ->
- e!id = Some v ->
- rs#r = v.
-Proof.
- intros until v.
- unfold find_var. caseEq (map.(map_vars)!id).
- intros r' EQ. monadSimpl. subst r'. intros.
- generalize (me_vars _ _ _ _ H _ _ H1). intros [r' [EQ' RS]].
- rewrite EQ' in EQ; injection EQ; intro; subst r'.
- assumption.
- intro; monadSimpl.
-Qed.
-Hint Resolve match_env_find_reg: rtlg.
-
-Lemma match_env_invariant:
- forall map e le rs rs',
- match_env map e le rs ->
- (forall r, (reg_in_map map r) -> rs'#r = rs#r) ->
- match_env map e le rs'.
-Proof.
- intros. apply mk_match_env.
- intros id v' E.
- generalize (me_vars _ _ _ _ H _ _ E). intros (r', (M, R)).
- exists r'. split. auto. rewrite <- R. apply H0.
- left. exists id. auto.
- transitivity rs ## (map_letvars map).
- apply list_map_exten. intros.
- symmetry. apply H0. right. auto.
- exact (me_letvars _ _ _ _ H).
-Qed.
-
-(** Matching between environments is preserved when an unmapped register
- (not corresponding to any Cminor variable) is assigned in the RTL
- execution. *)
-
-Lemma match_env_update_temp:
- forall map e le rs r v,
- match_env map e le rs ->
- ~(reg_in_map map r) ->
- match_env map e le (rs#r <- v).
-Proof.
- intros. apply match_env_invariant with rs; auto.
- intros. case (Reg.eq r r0); intro.
- subst r0; contradiction.
- apply Regmap.gso; auto.
-Qed.
-Hint Resolve match_env_update_temp: rtlg.
-
-(** Matching between environments is preserved by simultaneous
- assignment to a Cminor local variable (in the Cminor environments)
- and to the corresponding RTL pseudo-register (in the RTL register
- environment). *)
-
-Lemma match_env_update_var:
- forall map e le rs rs' id r v s s',
- map_wf map s ->
- find_var map id s = OK r s' ->
- match_env map e le rs ->
- rs'#r = v ->
- (forall x, x <> r -> rs'#x = rs#x) ->
- match_env map (PTree.set id v e) le rs'.
-Proof.
- intros until s'; intro MWF.
- unfold find_var in |- *. caseEq (map_vars map)!id.
- intros. monadInv H0. subst r0. apply mk_match_env.
- intros id' v' E. case (peq id' id); intros.
- subst id'. rewrite PTree.gss in E. injection E; intro; subst v'.
- exists r. split. auto. auto.
- rewrite PTree.gso in E; auto.
- elim (me_vars _ _ _ _ H1 _ _ E). intros r' (M, R).
- exists r'. split. assumption. rewrite <- R; apply H3; auto.
- red in |- *; intro. subst r'. apply n. eauto with rtlg.
- transitivity rs ## (map_letvars map).
- apply list_map_exten. intros. symmetry. apply H3.
- red in |- *; intro. subst x. eauto with rtlg.
- exact (me_letvars _ _ _ _ H1).
- intro; monadSimpl.
-Qed.
-
-Lemma match_env_letvar:
- forall map e le rs r v,
- match_env map e le rs ->
- rs#r = v ->
- match_env (add_letvar map r) e (v :: le) rs.
-Proof.
- intros. unfold add_letvar in |- *; apply mk_match_env; simpl in |- *.
- exact (me_vars _ _ _ _ H).
- rewrite H0. rewrite (me_letvars _ _ _ _ H). auto.
-Qed.
-
-Lemma match_env_exten:
- forall map e le rs1 rs2,
- (forall r, rs2#r = rs1#r) ->
- match_env map e le rs1 ->
- match_env map e le rs2.
-Proof.
- intros. apply mk_match_env.
- intros. generalize (me_vars _ _ _ _ H0 _ _ H1). intros (r, (M1, M2)).
- exists r. split. assumption. subst v. apply H.
- transitivity rs1 ## (map_letvars map).
- apply list_map_exten. intros. symmetry in |- *. apply H.
- exact (me_letvars _ _ _ _ H0).
-Qed.
-
-Lemma match_env_empty:
- forall map,
- map.(map_letvars) = nil ->
- match_env map (PTree.empty val) nil (Regmap.init Vundef).
-Proof.
- intros. apply mk_match_env.
- intros. rewrite PTree.gempty in H0. discriminate.
- rewrite H. reflexivity.
-Qed.
-
-(** The assignment of function arguments to local variables (on the Cminor
- side) and pseudo-registers (on the RTL side) preserves matching
- between environments. *)
-
-Lemma match_set_params_init_regs:
- forall il rl s1 map2 s2 vl,
- add_vars init_mapping il s1 = OK (rl, map2) s2 ->
- match_env map2 (set_params vl il) nil (init_regs vl rl)
- /\ (forall r, reg_fresh r s2 -> (init_regs vl rl)#r = Vundef).
-Proof.
- induction il; simpl in |- *; intros.
-
- monadInv H. intro; subst rl; simpl in |- *.
- split. apply match_env_empty. subst map2; auto.
- intros. apply Regmap.gi.
-
- monadInv H. intro EQ1; subst s0; subst y0; subst rl. clear H.
- monadInv EQ0. intro EQ2. subst x0; subst s0. simpl.
-
- assert (LV : map_letvars map2 = nil).
- transitivity (map_letvars y).
- eapply add_var_letenv; eauto.
- transitivity (map_letvars init_mapping).
- eapply add_vars_letenv; eauto.
- reflexivity.
-
- destruct vl.
- (* vl = nil *)
- generalize (IHil _ _ _ _ nil EQ). intros [ME UNDEF]. split.
- constructor. intros id v. subst map2. simpl.
- repeat rewrite PTree.gsspec; case (peq id a); intros.
- exists r; split. auto. rewrite Regmap.gi. congruence.
- destruct (me_vars _ _ _ _ ME id v H) as (r', (MV, IR)).
- exists r'. split. auto.
- replace (init_regs nil x) with (Regmap.init Vundef) in IR. auto.
- destruct x; reflexivity.
- rewrite LV; reflexivity.
- intros. apply Regmap.gi.
- (* vl = v :: vl *)
- generalize (IHil _ _ _ _ vl EQ). intros [ME UNDEF]. split.
- constructor. intros id v1. subst map2. simpl.
- repeat rewrite PTree.gsspec; case (peq id a); intros.
- exists r; split. auto. rewrite Regmap.gss. congruence.
- destruct (me_vars _ _ _ _ ME id v1 H) as (r', (MV, IR)).
- exists r'. split. auto. rewrite Regmap.gso. auto.
- apply valid_fresh_different with s.
- assert (MWF : map_wf y s).
- eapply add_vars_wf; eauto. apply init_mapping_wf.
- eauto with rtlg. eauto with rtlg.
- rewrite LV; reflexivity.
- intros. rewrite Regmap.gso. apply UNDEF. eauto with rtlg.
- apply sym_not_equal. eauto with rtlg.
-Qed.
-
-Lemma match_set_locals:
- forall map1 s1,
- map_wf map1 s1 ->
- forall il rl map2 s2 e le rs,
- match_env map1 e le rs ->
- (forall r, reg_fresh r s1 -> rs#r = Vundef) ->
- add_vars map1 il s1 = OK (rl, map2) s2 ->
- match_env map2 (set_locals il e) le rs.
-Proof.
- induction il; simpl in *; intros.
-
- monadInv H2. intros; subst map2; auto.
-
- monadInv H2. intros. subst s0; subst y0.
- assert (match_env y (set_locals il e) le rs).
- eapply IHil; eauto.
- monadInv EQ0. intro. subst s0; subst x0. rewrite <- H7.
- constructor.
- intros id v. simpl. repeat rewrite PTree.gsspec.
- case (peq id a); intros.
- exists r. split. auto. injection H5; intro; subst v.
- apply H1. apply reg_fresh_decr with s.
- eapply add_vars_incr; eauto.
- eauto with rtlg.
- eapply me_vars; eauto.
- simpl. eapply me_letvars; eauto.
-Qed.
-
-Lemma match_init_env_init_reg:
- forall params s0 rparams map1 s1 vars rvars map2 s2 vparams,
- add_vars init_mapping params s0 = OK (rparams, map1) s1 ->
- add_vars map1 vars s1 = OK (rvars, map2) s2 ->
- match_env map2 (set_locals vars (set_params vparams params))
- nil (init_regs vparams rparams).
-Proof.
- intros.
- generalize (match_set_params_init_regs _ _ _ _ _ vparams H).
- intros [A B].
- eapply match_set_locals; eauto.
- eapply add_vars_wf; eauto. apply init_mapping_wf.
-Qed.
-
-(** * Monotonicity properties of the state for the translation functions *)
-
-(** We show that the translation functions modify the state monotonically
- (in the sense of the [state_incr] relation). *)
-
-Lemma add_move_incr:
- forall r1 r2 nd s ns s',
- add_move r1 r2 nd s = OK ns s' ->
- state_incr s s'.
-Proof.
- intros until s'. unfold add_move.
- case (Reg.eq r1 r2); intro.
- monadSimpl. subst s'; auto with rtlg.
- intro; eauto with rtlg.
-Qed.
-Hint Resolve add_move_incr: rtlg.
-
-Scheme expr_ind3 := Induction for expr Sort Prop
- with condexpr_ind3 := Induction for condexpr Sort Prop
- with exprlist_ind3 := Induction for exprlist Sort Prop.
-
-Lemma expr_condexpr_exprlist_ind:
-forall (P : expr -> Prop) (P0 : condexpr -> Prop)
- (P1 : exprlist -> Prop),
- (forall i : ident, P (Evar i)) ->
- (forall (o : operation) (e : exprlist), P1 e -> P (Eop o e)) ->
- (forall (m : memory_chunk) (a : addressing) (e : exprlist),
- P1 e -> P (Eload m a e)) ->
- (forall (m : memory_chunk) (a : addressing) (e : exprlist),
- P1 e -> forall e0 : expr, P e0 -> P (Estore m a e e0)) ->
- (forall (s : signature) (e : expr),
- P e -> forall e0 : exprlist, P1 e0 -> P (Ecall s e e0)) ->
- (forall c : condexpr,
- P0 c ->
- forall e : expr,
- P e -> forall e0 : expr, P e0 -> P (Econdition c e e0)) ->
- (forall e : expr, P e -> forall e0 : expr, P e0 -> P (Elet e e0)) ->
- (forall n : nat, P (Eletvar n)) ->
- (forall e : expr, P e -> P (Ealloc e)) ->
- P0 CEtrue ->
- P0 CEfalse ->
- (forall (c : condition) (e : exprlist), P1 e -> P0 (CEcond c e)) ->
- (forall c : condexpr,
- P0 c ->
- forall c0 : condexpr,
- P0 c0 -> forall c1 : condexpr, P0 c1 -> P0 (CEcondition c c0 c1)) ->
- P1 Enil ->
- (forall e : expr,
- P e -> forall e0 : exprlist, P1 e0 -> P1 (Econs e e0)) ->
- (forall e : expr, P e) /\
- (forall ce : condexpr, P0 ce) /\
- (forall el : exprlist, P1 el).
-Proof.
- intros. split. apply (expr_ind3 P P0 P1); assumption.
- split. apply (condexpr_ind3 P P0 P1); assumption.
- apply (exprlist_ind3 P P0 P1); assumption.
-Qed.
-
-Definition transl_expr_incr_pred (a: expr) : Prop :=
- forall map rd nd s ns s',
- transl_expr map a rd nd s = OK ns s' -> state_incr s s'.
-Definition transl_condition_incr_pred (c: condexpr) : Prop :=
- forall map ntrue nfalse s ns s',
- transl_condition map c ntrue nfalse s = OK ns s' -> state_incr s s'.
-Definition transl_exprlist_incr_pred (al: exprlist) : Prop :=
- forall map rl nd s ns s',
- transl_exprlist map al rl nd s = OK ns s' -> state_incr s s'.
-
-Lemma transl_expr_condition_exprlist_incr:
- (forall a, transl_expr_incr_pred a) /\
- (forall c, transl_condition_incr_pred c) /\
- (forall al, transl_exprlist_incr_pred al).
-Proof.
- apply expr_condexpr_exprlist_ind;
- unfold transl_expr_incr_pred,
- transl_condition_incr_pred,
- transl_exprlist_incr_pred;
- simpl; intros;
- try (monadInv H); try (monadInv H0);
- try (monadInv H1); try (monadInv H2);
- eauto 6 with rtlg.
-
- intro EQ2.
- apply state_incr_trans3 with s0 s1 s2; eauto with rtlg.
-
- intro EQ4.
- apply state_incr_trans4 with s1 s2 s3 s4; eauto with rtlg.
-
- subst s'; auto with rtlg.
- subst s'; auto with rtlg.
- destruct rl; monadInv H. subst s'; auto with rtlg.
- destruct rl; monadInv H1. eauto with rtlg.
-Qed.
-
-Lemma transl_expr_incr:
- forall a map rd nd s ns s',
- transl_expr map a rd nd s = OK ns s' -> state_incr s s'.
-Proof (proj1 transl_expr_condition_exprlist_incr).
-
-Lemma transl_condition_incr:
- forall a map ntrue nfalse s ns s',
- transl_condition map a ntrue nfalse s = OK ns s' -> state_incr s s'.
-Proof (proj1 (proj2 transl_expr_condition_exprlist_incr)).
-
-Lemma transl_exprlist_incr:
- forall al map rl nd s ns s',
- transl_exprlist map al rl nd s = OK ns s' -> state_incr s s'.
-Proof (proj2 (proj2 transl_expr_condition_exprlist_incr)).
-
-Hint Resolve transl_expr_incr transl_condition_incr transl_exprlist_incr: rtlg.
-
-Lemma transl_exit_incr:
- forall nexits n s ns s',
- transl_exit nexits n s = OK ns s' ->
- state_incr s s'.
-Proof.
- intros until s'. unfold transl_exit.
- destruct (nth_error nexits n); intros; simplify_eq H; intros; subst s'.
- auto with rtlg.
-Qed.
-
-Hint Resolve transl_exit_incr: rtlg.
-
-Lemma transl_switch_incr:
- forall r nexits default cases s n s',
- transl_switch r nexits cases default s = OK n s' ->
- state_incr s s'.
-Proof.
- induction cases; simpl; intros.
- eauto with rtlg.
- destruct a as [key1 exit1].
- monadInv H. intros EQ2.
- apply state_incr_trans with s0. eauto.
- eauto with rtlg.
-Qed.
-
-Hint Resolve transl_switch_incr: rtlg.
-
-Lemma transl_stmt_incr:
- forall a map nd nexits nret rret s ns s',
- transl_stmt map a nd nexits nret rret s = OK ns s' ->
- state_incr s s'.
-Proof.
- induction a; simpl; intros.
-
- monadInv H. subst s'. auto with rtlg.
-
- monadInv H. eauto with rtlg.
-
- monadInv H. intro. apply state_incr_trans3 with s0 s1 s2; eauto with rtlg.
-
- monadInv H. eauto with rtlg.
-
- generalize H. case (more_likely c a1 a2); monadSimpl; eauto 6 with rtlg.
-
- monadInv H. subst s'.
- apply update_instr_incr with s0 s1 (Inop n0) n u; eauto with rtlg.
-
- eauto.
-
- eauto with rtlg.
-
- monadInv H. eauto 6 with rtlg.
-
- generalize H. destruct o; destruct rret; try monadSimpl.
- eauto with rtlg.
- subst s'; auto with rtlg.
-Qed.
-
-Hint Resolve transl_stmt_incr: rtlg.
-
diff --git a/backend/RTLgenspec.v b/backend/RTLgenspec.v
new file mode 100644
index 0000000..c46bdbb
--- /dev/null
+++ b/backend/RTLgenspec.v
@@ -0,0 +1,1455 @@
+(** Abstract specification of RTL generation *)
+
+(** In this module, we define inductive predicates that specify the
+ translations from Cminor to RTL performed by the functions in module
+ [RTLgen]. We then show that these functions satisfy these relational
+ specifications. The relational specifications will then be used
+ instead of the actual functions to show semantic equivalence between
+ the source Cminor code and the the generated RTL code
+ (see module [RTLgenproof]). *)
+
+Require Import Coqlib.
+Require Errors.
+Require Import Maps.
+Require Import AST.
+Require Import Integers.
+Require Import Values.
+Require Import Events.
+Require Import Mem.
+Require Import Globalenvs.
+Require Import Switch.
+Require Import Op.
+Require Import Registers.
+Require Import CminorSel.
+Require Import RTL.
+Require Import RTLgen.
+
+(** * Reasoning about monadic computations *)
+
+(** The tactics below simplify hypotheses of the form [f ... = OK x s]
+ where [f] is a monadic computation. For instance, the hypothesis
+ [(do x <- a; b) s = OK y s'] will generate the additional witnesses
+ [x], [s1] and the additional hypotheses
+ [a s = OK x s1] and [b x s1 = OK y s'], reflecting the fact that
+ both monadic computations [a] and [b] succeeded.
+*)
+
+Remark bind_inversion:
+ forall (A B: Set) (f: mon A) (g: A -> mon B) (y: B) (s1 s3: state),
+ bind f g s1 = OK y s3 ->
+ exists x, exists s2, f s1 = OK x s2 /\ g x s2 = OK y s3.
+Proof.
+ intros until s3. unfold bind. destruct (f s1); intros.
+ discriminate.
+ exists a; exists s; auto.
+Qed.
+
+Remark bind2_inversion:
+ forall (A B C: Set) (f: mon (A*B)) (g: A -> B -> mon C)
+ (z: C) (s1 s3: state),
+ bind2 f g s1 = OK z s3 ->
+ exists x, exists y, exists s2, f s1 = OK (x, y) s2 /\ g x y s2 = OK z s3.
+Proof.
+ intros until s3. unfold bind2, bind. destruct (f s1). congruence.
+ destruct p as [x y]; simpl; intro.
+ exists x; exists y; exists s; auto.
+Qed.
+
+Ltac monadInv1 H :=
+ match type of H with
+ | (OK _ _ = OK _ _) =>
+ inversion H; clear H; try subst
+ | (Error _ _ = OK _ _) =>
+ discriminate
+ | (ret _ _ = OK _ _) =>
+ inversion H; clear H; try subst
+ | (error _ _ = OK _ _) =>
+ discriminate
+ | (bind ?F ?G ?S = OK ?X ?S') =>
+ let x := fresh "x" in (
+ let s := fresh "s" in (
+ let EQ1 := fresh "EQ" in (
+ let EQ2 := fresh "EQ" in (
+ destruct (bind_inversion _ _ F G X S S' H) as [x [s [EQ1 EQ2]]];
+ clear H;
+ try (monadInv1 EQ2)))))
+ | (bind2 ?F ?G ?S = OK ?X ?S') =>
+ let x1 := fresh "x" in (
+ let x2 := fresh "x" in (
+ let s := fresh "s" in (
+ let EQ1 := fresh "EQ" in (
+ let EQ2 := fresh "EQ" in (
+ destruct (bind2_inversion _ _ _ F G X S S' H) as [x1 [x2 [s [EQ1 EQ2]]]];
+ clear H;
+ try (monadInv1 EQ2))))))
+ end.
+
+Ltac monadInv H :=
+ match type of H with
+ | (ret _ _ = OK _ _) => monadInv1 H
+ | (error _ _ = OK _ _) => monadInv1 H
+ | (bind ?F ?G ?S = OK ?X ?S') => monadInv1 H
+ | (bind2 ?F ?G ?S = OK ?X ?S') => monadInv1 H
+ | (?F _ _ _ _ _ _ _ _ = OK _ _) =>
+ ((progress simpl in H) || unfold F in H); monadInv1 H
+ | (?F _ _ _ _ _ _ _ = OK _ _) =>
+ ((progress simpl in H) || unfold F in H); monadInv1 H
+ | (?F _ _ _ _ _ _ = OK _ _) =>
+ ((progress simpl in H) || unfold F in H); monadInv1 H
+ | (?F _ _ _ _ _ = OK _ _) =>
+ ((progress simpl in H) || unfold F in H); monadInv1 H
+ | (?F _ _ _ _ = OK _ _) =>
+ ((progress simpl in H) || unfold F in H); monadInv1 H
+ | (?F _ _ _ = OK _ _) =>
+ ((progress simpl in H) || unfold F in H); monadInv1 H
+ | (?F _ _ = OK _ _) =>
+ ((progress simpl in H) || unfold F in H); monadInv1 H
+ | (?F _ = OK _ _) =>
+ ((progress simpl in H) || unfold F in H); monadInv1 H
+ end.
+
+(** * Monotonicity properties of the state *)
+
+(** Operations over the global state satisfy a crucial monotonicity property:
+ nodes are only added to the CFG, but never removed nor their instructions
+ changed; similarly, fresh nodes and fresh registers are only consumed,
+ but never reused. This property is captured by the following predicate
+ over states, which we show is a partial order. *)
+
+Inductive state_incr: state -> state -> Prop :=
+ state_incr_intro:
+ forall (s1 s2: state),
+ Ple s1.(st_nextnode) s2.(st_nextnode) ->
+ Ple s1.(st_nextreg) s2.(st_nextreg) ->
+ (forall pc, Plt pc s1.(st_nextnode) -> s2.(st_code)!pc = s1.(st_code)!pc) ->
+ state_incr s1 s2.
+
+Lemma instr_at_incr:
+ forall s1 s2 n i,
+ state_incr s1 s2 -> s1.(st_code)!n = Some i -> s2.(st_code)!n = Some i.
+Proof.
+ intros. inversion H.
+ rewrite H3. auto. elim (st_wf s1 n); intro.
+ assumption. congruence.
+Qed.
+
+Lemma state_incr_refl:
+ forall s, state_incr s s.
+Proof.
+ intros. apply state_incr_intro.
+ apply Ple_refl. apply Ple_refl. intros; auto.
+Qed.
+Hint Resolve state_incr_refl: rtlg.
+
+Lemma state_incr_trans:
+ forall s1 s2 s3, state_incr s1 s2 -> state_incr s2 s3 -> state_incr s1 s3.
+Proof.
+ intros. inversion H. inversion H0. apply state_incr_intro.
+ apply Ple_trans with (st_nextnode s2); assumption.
+ apply Ple_trans with (st_nextreg s2); assumption.
+ intros. transitivity (s2.(st_code)!pc).
+ apply H8. apply Plt_Ple_trans with s1.(st_nextnode); auto.
+ apply H3; auto.
+Qed.
+Hint Resolve state_incr_trans: rtlg.
+
+(** The following relation between two states is a weaker version of
+ [state_incr]. It permits changing the contents at an already reserved
+ graph node, but only from [None] to [Some i]. *)
+
+Definition state_extends (s1 s2: state): Prop :=
+ forall pc,
+ s1.(st_code)!pc = None \/ s2.(st_code)!pc = s1.(st_code)!pc.
+
+Lemma instr_at_extends:
+ forall s1 s2 pc i,
+ state_extends s1 s2 ->
+ s1.(st_code)!pc = Some i -> s2.(st_code)!pc = Some i.
+Proof.
+ intros. elim (H pc); intro. congruence. congruence.
+Qed.
+
+Lemma state_incr_extends:
+ forall s1 s2,
+ state_incr s1 s2 -> state_extends s1 s2.
+Proof.
+ unfold state_extends; intros. inversion H.
+ case (plt pc s1.(st_nextnode)); intro.
+ right; apply H2; auto.
+ left. elim (s1.(st_wf) pc); intro.
+ elim (n H5). auto.
+Qed.
+Hint Resolve state_incr_extends.
+
+(** * Validity and freshness of registers *)
+
+(** An RTL pseudo-register is valid in a given state if it was created
+ earlier, that is, it is less than the next fresh register of the state.
+ Otherwise, the pseudo-register is said to be fresh. *)
+
+Definition reg_valid (r: reg) (s: state) : Prop :=
+ Plt r s.(st_nextreg).
+
+Definition reg_fresh (r: reg) (s: state) : Prop :=
+ ~(Plt r s.(st_nextreg)).
+
+Lemma valid_fresh_absurd:
+ forall r s, reg_valid r s -> reg_fresh r s -> False.
+Proof.
+ intros r s. unfold reg_valid, reg_fresh; case r; tauto.
+Qed.
+Hint Resolve valid_fresh_absurd: rtlg.
+
+Lemma valid_fresh_different:
+ forall r1 r2 s, reg_valid r1 s -> reg_fresh r2 s -> r1 <> r2.
+Proof.
+ unfold not; intros. subst r2. eauto with rtlg.
+Qed.
+Hint Resolve valid_fresh_different: rtlg.
+
+Lemma reg_valid_incr:
+ forall r s1 s2, state_incr s1 s2 -> reg_valid r s1 -> reg_valid r s2.
+Proof.
+ intros r s1 s2 INCR.
+ inversion INCR.
+ unfold reg_valid. intros; apply Plt_Ple_trans with (st_nextreg s1); auto.
+Qed.
+Hint Resolve reg_valid_incr: rtlg.
+
+Lemma reg_fresh_decr:
+ forall r s1 s2, state_incr s1 s2 -> reg_fresh r s2 -> reg_fresh r s1.
+Proof.
+ intros r s1 s2 INCR. inversion INCR.
+ unfold reg_fresh; unfold not; intros.
+ apply H4. apply Plt_Ple_trans with (st_nextreg s1); auto.
+Qed.
+Hint Resolve reg_fresh_decr: rtlg.
+
+(** Validity of a list of registers. *)
+
+Definition regs_valid (rl: list reg) (s: state) : Prop :=
+ forall r, In r rl -> reg_valid r s.
+
+Lemma regs_valid_nil:
+ forall s, regs_valid nil s.
+Proof.
+ intros; red; intros. elim H.
+Qed.
+Hint Resolve regs_valid_nil: rtlg.
+
+Lemma regs_valid_cons:
+ forall r1 rl s,
+ reg_valid r1 s -> regs_valid rl s -> regs_valid (r1 :: rl) s.
+Proof.
+ intros; red; intros. elim H1; intro. subst r1; auto. auto.
+Qed.
+
+Lemma regs_valid_incr:
+ forall s1 s2 rl, state_incr s1 s2 -> regs_valid rl s1 -> regs_valid rl s2.
+Proof.
+ unfold regs_valid; intros; eauto with rtlg.
+Qed.
+Hint Resolve regs_valid_incr: rtlg.
+
+(** A register is ``in'' a mapping if it is associated with a Cminor
+ local or let-bound variable. *)
+
+Definition reg_in_map (m: mapping) (r: reg) : Prop :=
+ (exists id, m.(map_vars)!id = Some r) \/ In r m.(map_letvars).
+
+(** A compilation environment (mapping) is valid in a given state if
+ the registers associated with Cminor local variables and let-bound variables
+ are valid in the state. *)
+
+Definition map_valid (m: mapping) (s: state) : Prop :=
+ forall r, reg_in_map m r -> reg_valid r s.
+
+Lemma map_valid_incr:
+ forall s1 s2 m,
+ state_incr s1 s2 -> map_valid m s1 -> map_valid m s2.
+Proof.
+ unfold map_valid; intros; eauto with rtlg.
+Qed.
+Hint Resolve map_valid_incr: rtlg.
+
+(** * Properties of basic operations over the state *)
+
+(** Properties of [add_instr]. *)
+
+Lemma add_instr_incr:
+ forall s1 s2 i n,
+ add_instr i s1 = OK n s2 -> state_incr s1 s2.
+Proof.
+ intros. monadInv H.
+ apply state_incr_intro; simpl.
+ apply Ple_succ.
+ apply Ple_refl.
+ intros. apply PTree.gso; apply Plt_ne; auto.
+Qed.
+Hint Resolve add_instr_incr: rtlg.
+
+Lemma add_instr_at:
+ forall s1 s2 i n,
+ add_instr i s1 = OK n s2 -> s2.(st_code)!n = Some i.
+Proof.
+ intros. monadInv H. simpl. apply PTree.gss.
+Qed.
+Hint Resolve add_instr_at.
+
+(** Properties of [reserve_instr] and [update_instr]. *)
+
+Lemma reserve_instr_incr:
+ forall s1 s2 n,
+ reserve_instr s1 = OK n s2 -> state_incr s1 s2.
+Proof.
+ intros. monadInv H.
+ apply state_incr_intro; simpl.
+ apply Ple_succ.
+ apply Ple_refl.
+ auto.
+Qed.
+
+Lemma update_instr_incr:
+ forall s1 s2 s3 s4 i n t,
+ reserve_instr s1 = OK n s2 ->
+ state_incr s2 s3 ->
+ update_instr n i s3 = OK t s4 ->
+ state_incr s1 s4.
+Proof.
+ intros.
+ generalize H1; clear H1; unfold update_instr.
+ case (plt n (st_nextnode s3)); intros. 2: discriminate.
+ inv H1. inv H0. monadInv H; simpl in *.
+ apply state_incr_intro; simpl.
+ eapply Ple_trans; eauto. apply Plt_Ple. apply Plt_succ.
+ auto.
+ intros. rewrite PTree.gso.
+ apply H3. apply Plt_trans_succ; auto.
+ apply Plt_ne. auto.
+Qed.
+
+Lemma update_instr_extends:
+ forall s1 s2 s3 s4 i n t,
+ reserve_instr s1 = OK n s2 ->
+ state_incr s2 s3 ->
+ update_instr n i s3 = OK t s4 ->
+ state_extends s3 s4.
+Proof.
+ intros. injection H. intros EQ1 EQ2.
+ red; intros.
+ case (peq pc n); intro.
+ subst pc. left. inversion H0. rewrite H4. rewrite <- EQ1; simpl.
+ destruct (s1.(st_wf) n). rewrite <- EQ2 in H7. elim (Plt_strict _ H7).
+ auto.
+ rewrite <- EQ1; rewrite <- EQ2; simpl. apply Plt_succ.
+ generalize H1; unfold update_instr.
+ case (plt n s3.(st_nextnode)); intros; inv H2.
+ right; simpl. apply PTree.gso; auto.
+Qed.
+
+(** Properties of [new_reg]. *)
+
+Lemma new_reg_incr:
+ forall s1 s2 r, new_reg s1 = OK r s2 -> state_incr s1 s2.
+Proof.
+ intros. monadInv H.
+ apply state_incr_intro; simpl.
+ apply Ple_refl. apply Ple_succ. auto.
+Qed.
+Hint Resolve new_reg_incr: rtlg.
+
+Lemma new_reg_valid:
+ forall s1 s2 r,
+ new_reg s1 = OK r s2 -> reg_valid r s2.
+Proof.
+ intros. monadInv H.
+ unfold reg_valid; simpl. apply Plt_succ.
+Qed.
+Hint Resolve new_reg_valid: rtlg.
+
+Lemma new_reg_fresh:
+ forall s1 s2 r,
+ new_reg s1 = OK r s2 -> reg_fresh r s1.
+Proof.
+ intros. monadInv H.
+ unfold reg_fresh; simpl.
+ exact (Plt_strict _).
+Qed.
+Hint Resolve new_reg_fresh: rtlg.
+
+Lemma new_reg_not_in_map:
+ forall s1 s2 m r,
+ new_reg s1 = OK r s2 -> map_valid m s1 -> ~(reg_in_map m r).
+Proof.
+ unfold not; intros; eauto with rtlg.
+Qed.
+Hint Resolve new_reg_not_in_map: rtlg.
+
+(** * Properties of operations over compilation environments *)
+
+Lemma init_mapping_valid:
+ forall s, map_valid init_mapping s.
+Proof.
+ unfold map_valid, init_mapping.
+ intros s r [[id A] | B].
+ simpl in A. rewrite PTree.gempty in A; discriminate.
+ simpl in B. tauto.
+Qed.
+
+(** Properties of [find_var]. *)
+
+Lemma find_var_incr:
+ forall s1 s2 map name r,
+ find_var map name s1 = OK r s2 -> state_incr s1 s2.
+Proof.
+ intros until r. unfold find_var.
+ case (map_vars map)!name; intros; monadInv H.
+ auto with rtlg.
+Qed.
+Hint Resolve find_var_incr: rtlg.
+
+Lemma find_var_in_map:
+ forall s1 s2 map name r,
+ find_var map name s1 = OK r s2 -> reg_in_map map r.
+Proof.
+ intros until r. unfold find_var; caseEq (map.(map_vars)!name).
+ intros. inv H0. left; exists name; auto.
+ intros. inv H0.
+Qed.
+Hint Resolve find_var_in_map: rtlg.
+
+Lemma find_var_valid:
+ forall s1 s2 map name r,
+ find_var map name s1 = OK r s2 -> map_valid map s1 -> reg_valid r s1.
+Proof.
+ eauto with rtlg.
+Qed.
+Hint Resolve find_var_valid: rtlg.
+
+(** Properties of [find_letvar]. *)
+
+Lemma find_letvar_incr:
+ forall s1 s2 map idx r,
+ find_letvar map idx s1 = OK r s2 -> state_incr s1 s2.
+Proof.
+ intros until r. unfold find_letvar.
+ case (nth_error (map_letvars map) idx); intros; monadInv H.
+ auto with rtlg.
+Qed.
+Hint Resolve find_letvar_incr: rtlg.
+
+Lemma find_letvar_in_map:
+ forall s1 s2 map idx r,
+ find_letvar map idx s1 = OK r s2 -> reg_in_map map r.
+Proof.
+ intros until r. unfold find_letvar.
+ caseEq (nth_error (map_letvars map) idx); intros; monadInv H0.
+ right; apply nth_error_in with idx; auto.
+Qed.
+Hint Resolve find_letvar_in_map: rtlg.
+
+Lemma find_letvar_valid:
+ forall s1 s2 map idx r,
+ find_letvar map idx s1 = OK r s2 -> map_valid map s1 -> reg_valid r s1.
+Proof.
+ eauto with rtlg.
+Qed.
+Hint Resolve find_letvar_valid: rtlg.
+
+(** Properties of [add_var]. *)
+
+Lemma add_var_valid:
+ forall s1 s2 map1 map2 name r,
+ add_var map1 name s1 = OK (r, map2) s2 ->
+ map_valid map1 s1 ->
+ reg_valid r s2 /\ map_valid map2 s2.
+Proof.
+ intros. monadInv H.
+ split. eauto with rtlg.
+ inversion EQ. subst. red. intros r' [[id A] | B].
+ simpl in A. rewrite PTree.gsspec in A. destruct (peq id name).
+ inv A. eauto with rtlg.
+ apply reg_valid_incr with s1. eauto with rtlg.
+ apply H0. left; exists id; auto.
+ simpl in B. apply reg_valid_incr with s1. eauto with rtlg.
+ apply H0. right; auto.
+Qed.
+
+Lemma add_var_incr:
+ forall s1 s2 map name rm,
+ add_var map name s1 = OK rm s2 -> state_incr s1 s2.
+Proof.
+ intros. monadInv H. eauto with rtlg.
+Qed.
+Hint Resolve add_var_incr: rtlg.
+
+Lemma add_var_find:
+ forall s1 s2 map name r map',
+ add_var map name s1 = OK (r,map') s2 -> map'.(map_vars)!name = Some r.
+Proof.
+ intros. monadInv H. simpl. apply PTree.gss.
+Qed.
+
+Lemma add_vars_incr:
+ forall names s1 s2 map r,
+ add_vars map names s1 = OK r s2 -> state_incr s1 s2.
+Proof.
+ induction names; simpl; intros; monadInv H.
+ auto with rtlg.
+ eauto with rtlg.
+Qed.
+
+Lemma add_vars_valid:
+ forall namel s1 s2 map1 map2 rl,
+ add_vars map1 namel s1 = OK (rl, map2) s2 ->
+ map_valid map1 s1 ->
+ regs_valid rl s2 /\ map_valid map2 s2.
+Proof.
+ induction namel; simpl; intros; monadInv H.
+ split. red; simpl; intros; tauto. auto.
+ exploit IHnamel; eauto. intros [A B].
+ exploit add_var_valid; eauto. intros [C D].
+ exploit add_var_incr; eauto. intros INCR.
+ split. apply regs_valid_cons; eauto with rtlg.
+ auto.
+Qed.
+
+Lemma add_var_letenv:
+ forall map1 i s1 r map2 s2,
+ add_var map1 i s1 = OK (r, map2) s2 ->
+ map2.(map_letvars) = map1.(map_letvars).
+Proof.
+ intros; monadInv H. reflexivity.
+Qed.
+
+Lemma add_vars_letenv:
+ forall il map1 s1 rl map2 s2,
+ add_vars map1 il s1 = OK (rl, map2) s2 ->
+ map2.(map_letvars) = map1.(map_letvars).
+Proof.
+ induction il; simpl; intros; monadInv H.
+ reflexivity.
+ transitivity (map_letvars x0).
+ eapply add_var_letenv; eauto.
+ eauto.
+Qed.
+
+(** Properties of [add_letvar]. *)
+
+Lemma add_letvar_valid:
+ forall map s r,
+ map_valid map s ->
+ reg_valid r s ->
+ map_valid (add_letvar map r) s.
+Proof.
+ intros; red; intros.
+ destruct H1 as [[id A]|B].
+ simpl in A. apply H. left; exists id; auto.
+ simpl in B. elim B; intro.
+ subst r0; auto. apply H. right; auto.
+Qed.
+
+(** * Properties of [alloc_reg] and [alloc_regs] *)
+
+Lemma alloc_reg_incr:
+ forall a s1 s2 map r,
+ alloc_reg map a s1 = OK r s2 -> state_incr s1 s2.
+Proof.
+ intros until r. unfold alloc_reg.
+ case a; eauto with rtlg.
+Qed.
+Hint Resolve alloc_reg_incr: rtlg.
+
+Lemma alloc_reg_valid:
+ forall a s1 s2 map r,
+ map_valid map s1 ->
+ alloc_reg map a s1 = OK r s2 -> reg_valid r s2.
+Proof.
+ intros until r. unfold alloc_reg.
+ case a; eauto with rtlg.
+Qed.
+Hint Resolve alloc_reg_valid: rtlg.
+
+Lemma alloc_reg_fresh_or_in_map:
+ forall map a s r s',
+ map_valid map s ->
+ alloc_reg map a s = OK r s' ->
+ reg_in_map map r \/ reg_fresh r s.
+Proof.
+ intros until s'. unfold alloc_reg.
+ destruct a; intros; try (right; eauto with rtlg; fail).
+ left; eauto with rtlg.
+ left; eauto with rtlg.
+Qed.
+
+Lemma alloc_regs_incr:
+ forall al s1 s2 map rl,
+ alloc_regs map al s1 = OK rl s2 -> state_incr s1 s2.
+Proof.
+ induction al; simpl; intros; monadInv H; eauto with rtlg.
+Qed.
+Hint Resolve alloc_regs_incr: rtlg.
+
+Lemma alloc_regs_valid:
+ forall al s1 s2 map rl,
+ map_valid map s1 ->
+ alloc_regs map al s1 = OK rl s2 ->
+ regs_valid rl s2.
+Proof.
+ induction al; simpl; intros; monadInv H0.
+ apply regs_valid_nil.
+ apply regs_valid_cons. eauto with rtlg. eauto with rtlg.
+Qed.
+Hint Resolve alloc_regs_valid: rtlg.
+
+Lemma alloc_regs_fresh_or_in_map:
+ forall map al s rl s',
+ map_valid map s ->
+ alloc_regs map al s = OK rl s' ->
+ forall r, In r rl -> reg_in_map map r \/ reg_fresh r s.
+Proof.
+ induction al; simpl; intros; monadInv H0.
+ elim H1.
+ elim H1; intro.
+ subst r.
+ eapply alloc_reg_fresh_or_in_map; eauto.
+ exploit IHal. apply map_valid_incr with s0; eauto with rtlg. eauto. eauto.
+ intros [A|B]. auto. right; eauto with rtlg.
+Qed.
+
+(** A register is an adequate target for holding the value of an
+ expression if
+- either the register is associated with a Cminor let-bound variable
+ or a Cminor local variable;
+- or the register is not associated with any Cminor variable
+ and does not belong to the preserved set [pr]. *)
+
+Inductive target_reg_ok (map: mapping) (pr: list reg): expr -> reg -> Prop :=
+ | target_reg_var:
+ forall id r,
+ map.(map_vars)!id = Some r ->
+ target_reg_ok map pr (Evar id) r
+ | target_reg_letvar:
+ forall idx r,
+ nth_error map.(map_letvars) idx = Some r ->
+ target_reg_ok map pr (Eletvar idx) r
+ | target_reg_other:
+ forall a r,
+ ~(reg_in_map map r) -> ~In r pr ->
+ target_reg_ok map pr a r.
+
+Inductive target_regs_ok (map: mapping) (pr: list reg): exprlist -> list reg -> Prop :=
+ | target_regs_nil:
+ target_regs_ok map pr Enil nil
+ | target_regs_cons: forall a1 al r1 rl,
+ target_reg_ok map pr a1 r1 ->
+ target_regs_ok map (r1 :: pr) al rl ->
+ target_regs_ok map pr (Econs a1 al) (r1 :: rl).
+
+Lemma target_reg_ok_append:
+ forall map pr a r,
+ target_reg_ok map pr a r ->
+ forall pr',
+ (forall r', In r' pr' -> reg_in_map map r' \/ r' <> r) ->
+ target_reg_ok map (pr' ++ pr) a r.
+Proof.
+ induction 1; intros.
+ constructor; auto.
+ constructor; auto.
+ constructor; auto. red; intros.
+ elim (in_app_or _ _ _ H2); intro.
+ generalize (H1 _ H3). tauto. tauto.
+Qed.
+
+Lemma target_reg_ok_cons:
+ forall map pr a r,
+ target_reg_ok map pr a r ->
+ forall r',
+ reg_in_map map r' \/ r' <> r ->
+ target_reg_ok map (r' :: pr) a r.
+Proof.
+ intros. change (r' :: pr) with ((r' :: nil) ++ pr).
+ apply target_reg_ok_append; auto.
+ intros r'' [A|B]. subst r''; auto. contradiction.
+Qed.
+
+Lemma new_reg_target_ok:
+ forall map pr s1 a r s2,
+ map_valid map s1 ->
+ regs_valid pr s1 ->
+ new_reg s1 = OK r s2 ->
+ target_reg_ok map pr a r.
+Proof.
+ intros. constructor.
+ red; intro. apply valid_fresh_absurd with r s1.
+ eauto with rtlg. eauto with rtlg.
+ red; intro. apply valid_fresh_absurd with r s1.
+ auto. eauto with rtlg.
+Qed.
+
+Lemma alloc_reg_target_ok:
+ forall map pr s1 a r s2,
+ map_valid map s1 ->
+ regs_valid pr s1 ->
+ alloc_reg map a s1 = OK r s2 ->
+ target_reg_ok map pr a r.
+Proof.
+ intros. unfold alloc_reg in H1. destruct a;
+ try (eapply new_reg_target_ok; eauto; fail).
+ (* Evar *)
+ generalize H1; unfold find_var. caseEq (map_vars map)!i; intros.
+ inv H3. constructor. auto. inv H3.
+ (* Elet *)
+ generalize H1; unfold find_letvar. caseEq (nth_error (map_letvars map) n); intros.
+ inv H3. constructor. auto. inv H3.
+Qed.
+
+Lemma alloc_regs_target_ok:
+ forall map al pr s1 rl s2,
+ map_valid map s1 ->
+ regs_valid pr s1 ->
+ alloc_regs map al s1 = OK rl s2 ->
+ target_regs_ok map pr al rl.
+Proof.
+ induction al; intros; monadInv H1.
+ constructor.
+ constructor.
+ eapply alloc_reg_target_ok; eauto.
+ apply IHal with s s2; eauto with rtlg.
+ apply regs_valid_cons; eauto with rtlg.
+Qed.
+
+Hint Resolve new_reg_target_ok alloc_reg_target_ok alloc_regs_target_ok: rtlg.
+
+(** The following predicate is a variant of [target_reg_ok] used
+ to characterize registers that are adequate for holding the return
+ value of a function. *)
+
+Inductive return_reg_ok: state -> mapping -> option reg -> Prop :=
+ | return_reg_ok_none:
+ forall s map,
+ return_reg_ok s map None
+ | return_reg_ok_some:
+ forall s map r,
+ ~(reg_in_map map r) -> reg_valid r s ->
+ return_reg_ok s map (Some r).
+
+Lemma return_reg_ok_incr:
+ forall s map rret, return_reg_ok s map rret ->
+ forall s', state_incr s s' -> return_reg_ok s' map rret.
+Proof.
+ induction 1; intros; econstructor; eauto with rtlg.
+Qed.
+Hint Resolve return_reg_ok_incr: rtlg.
+
+Lemma new_reg_return_ok:
+ forall s1 r s2 map sig,
+ new_reg s1 = OK r s2 ->
+ map_valid map s1 ->
+ return_reg_ok s2 map (ret_reg sig r).
+Proof.
+ intros. unfold ret_reg. destruct (sig_res sig); constructor.
+ eauto with rtlg. eauto with rtlg.
+Qed.
+
+(** * Relational specification of the translation *)
+
+(** We now define inductive predicates that characterize the fact that
+ the control-flow graph produced by compilation of a Cminor function
+ contains sub-graphs that correspond to the translation of each
+ Cminor expression or statement in the original code. *)
+
+(** [tr_move c ns rs nd rd] holds if the graph [c], between nodes [ns]
+ and [nd], contains instructions that move the value of register [rs]
+ to register [rd]. *)
+
+Inductive tr_move (c: code):
+ node -> reg -> node -> reg -> Prop :=
+ | tr_move_0: forall n r,
+ tr_move c n r n r
+ | tr_move_1: forall ns rs nd rd,
+ c!ns = Some (Iop Omove (rs :: nil) rd nd) ->
+ tr_move c ns rs nd rd.
+
+(** [tr_expr c map pr expr ns nd rd] holds if the graph [c],
+ between nodes [ns] and [nd], contains instructions that compute the
+ value of the Cminor expression [expr] and deposit this value in
+ register [rd]. [map] is a mapping from Cminor variables to the
+ corresponding RTL registers. [pr] is a list of RTL registers whose
+ values must be preserved during this computation. All registers
+ mentioned in [map] must also be preserved during this computation.
+ To ensure this, we demand that the result registers of the instructions
+ appearing on the path from [ns] to [nd] are neither in [pr] nor in [map].
+*)
+
+Inductive tr_expr (c: code):
+ mapping -> list reg -> expr -> node -> node -> reg -> Prop :=
+ | tr_Evar: forall map pr id ns nd r rd,
+ map.(map_vars)!id = Some r ->
+ (rd = r \/ ~reg_in_map map rd /\ ~In rd pr) ->
+ tr_move c ns r nd rd ->
+ tr_expr c map pr (Evar id) ns nd rd
+ | tr_Eop: forall map pr op al ns nd rd n1 rl,
+ tr_exprlist c map pr al ns n1 rl ->
+ c!n1 = Some (Iop op rl rd nd) ->
+ ~reg_in_map map rd -> ~In rd pr ->
+ tr_expr c map pr (Eop op al) ns nd rd
+ | tr_Eload: forall map pr chunk addr al ns nd rd n1 rl,
+ tr_exprlist c map pr al ns n1 rl ->
+ c!n1 = Some (Iload chunk addr rl rd nd) ->
+ ~reg_in_map map rd -> ~In rd pr ->
+ tr_expr c map pr (Eload chunk addr al) ns nd rd
+ | tr_Estore: forall map pr chunk addr al b ns nd rd n1 rl n2,
+ tr_exprlist c map pr al ns n1 rl ->
+ tr_expr c map (rl ++ pr) b n1 n2 rd ->
+ c!n2 = Some (Istore chunk addr rl rd nd) ->
+ tr_expr c map pr (Estore chunk addr al b) ns nd rd
+ | tr_Ecall: forall map pr sig b cl ns nd rd n1 rf n2 rargs,
+ tr_expr c map pr b ns n1 rf ->
+ tr_exprlist c map (rf :: pr) cl n1 n2 rargs ->
+ c!n2 = Some (Icall sig (inl _ rf) rargs rd nd) ->
+ ~reg_in_map map rd -> ~In rd pr ->
+ tr_expr c map pr (Ecall sig b cl) ns nd rd
+ | tr_Econdition: forall map pr b ifso ifnot ns nd rd ntrue nfalse,
+ tr_condition c map pr b ns ntrue nfalse ->
+ tr_expr c map pr ifso ntrue nd rd ->
+ tr_expr c map pr ifnot nfalse nd rd ->
+ tr_expr c map pr (Econdition b ifso ifnot) ns nd rd
+ | tr_Elet: forall map pr b1 b2 ns nd rd n1 r,
+ ~reg_in_map map r ->
+ tr_expr c map pr b1 ns n1 r ->
+ tr_expr c (add_letvar map r) pr b2 n1 nd rd ->
+ tr_expr c map pr (Elet b1 b2) ns nd rd
+ | tr_Eletvar: forall map pr n ns nd rd r,
+ List.nth_error map.(map_letvars) n = Some r ->
+ (rd = r \/ ~reg_in_map map rd /\ ~In rd pr) ->
+ tr_move c ns r nd rd ->
+ tr_expr c map pr (Eletvar n) ns nd rd
+ | tr_Ealloc: forall map pr a ns nd rd n1 r,
+ tr_expr c map pr a ns n1 r ->
+ c!n1 = Some (Ialloc r rd nd) ->
+ ~reg_in_map map rd -> ~In rd pr ->
+ tr_expr c map pr (Ealloc a) ns nd rd
+
+(** [tr_expr c map pr cond ns ntrue nfalse rd] holds if the graph [c],
+ starting at node [ns], contains instructions that compute the truth
+ value of the Cminor conditional expression [cond] and terminate
+ on node [ntrue] if the condition holds and on node [nfalse] otherwise. *)
+
+with tr_condition (c: code):
+ mapping -> list reg -> condexpr -> node -> node -> node -> Prop :=
+ | tr_CEtrue: forall map pr ntrue nfalse,
+ tr_condition c map pr CEtrue ntrue ntrue nfalse
+ | tr_CEfalse: forall map pr ntrue nfalse,
+ tr_condition c map pr CEfalse nfalse ntrue nfalse
+ | tr_CEcond: forall map pr cond bl ns ntrue nfalse n1 rl,
+ tr_exprlist c map pr bl ns n1 rl ->
+ c!n1 = Some (Icond cond rl ntrue nfalse) ->
+ tr_condition c map pr (CEcond cond bl) ns ntrue nfalse
+ | tr_CEcondition: forall map pr b ifso ifnot ns ntrue nfalse ntrue' nfalse',
+ tr_condition c map pr b ns ntrue' nfalse' ->
+ tr_condition c map pr ifso ntrue' ntrue nfalse ->
+ tr_condition c map pr ifnot nfalse' ntrue nfalse ->
+ tr_condition c map pr (CEcondition b ifso ifnot) ns ntrue nfalse
+
+(** [tr_exprlist c map pr exprs ns nd rds] holds if the graph [c],
+ between nodes [ns] and [nd], contains instructions that compute the values
+ of the list of Cminor expression [exprlist] and deposit these values
+ in registers [rds]. *)
+
+with tr_exprlist (c: code):
+ mapping -> list reg -> exprlist -> node -> node -> list reg -> Prop :=
+ | tr_Enil: forall map pr n,
+ tr_exprlist c map pr Enil n n nil
+ | tr_Econs: forall map pr a1 al ns nd r1 rl n1,
+ tr_expr c map pr a1 ns n1 r1 ->
+ tr_exprlist c map (r1 :: pr) al n1 nd rl ->
+ tr_exprlist c map pr (Econs a1 al) ns nd (r1 :: rl).
+
+(** Auxiliary for the compilation of [switch] statements. *)
+
+Inductive tr_switch
+ (c: code) (r: reg) (nexits: list node):
+ comptree -> node -> Prop :=
+ | tr_switch_action: forall act n,
+ nth_error nexits act = Some n ->
+ tr_switch c r nexits (CTaction act) n
+ | tr_switch_ifeq: forall key act t' n ncont nfound,
+ tr_switch c r nexits t' ncont ->
+ nth_error nexits act = Some nfound ->
+ c!n = Some(Icond (Ccompimm Ceq key) (r :: nil) nfound ncont) ->
+ tr_switch c r nexits (CTifeq key act t') n
+ | tr_switch_iflt: forall key t1 t2 n n1 n2,
+ tr_switch c r nexits t1 n1 ->
+ tr_switch c r nexits t2 n2 ->
+ c!n = Some(Icond (Ccompuimm Clt key) (r :: nil) n1 n2) ->
+ tr_switch c r nexits (CTiflt key t1 t2) n.
+
+(** [tr_stmt c map stmt ns ncont nexits nret rret] holds if the graph [c],
+ starting at node [ns], contains instructions that perform the Cminor
+ statement [stmt]. These instructions branch to node [ncont] if
+ the statement terminates normally, to the [n]-th node in [nexits]
+ if the statement terminates prematurely on a [exit n] statement,
+ and to [nret] if the statement terminates prematurely on a [return]
+ statement. Moreover, if the [return] statement has an argument,
+ its value is deposited in register [rret]. *)
+
+Inductive tr_stmt (c: code) (map: mapping):
+ stmt -> node -> node -> list node -> node -> option reg -> Prop :=
+ | tr_Sskip: forall ns nexits nret rret,
+ tr_stmt c map Sskip ns ns nexits nret rret
+ | tr_Sexpr: forall a ns nd nexits nret rret r,
+ tr_expr c map nil a ns nd r ->
+ tr_stmt c map (Sexpr a) ns nd nexits nret rret
+ | tr_Sassign: forall id a ns nd nexits nret rret rv rt n,
+ map.(map_vars)!id = Some rv ->
+ tr_move c n rt nd rv ->
+ tr_expr c map nil a ns n rt ->
+ tr_stmt c map (Sassign id a) ns nd nexits nret rret
+ | tr_Sseq: forall s1 s2 ns nd nexits nret rret n,
+ tr_stmt c map s2 n nd nexits nret rret ->
+ tr_stmt c map s1 ns n nexits nret rret ->
+ tr_stmt c map (Sseq s1 s2) ns nd nexits nret rret
+ | tr_Sifthenelse: forall a strue sfalse ns nd nexits nret rret ntrue nfalse,
+ tr_stmt c map strue ntrue nd nexits nret rret ->
+ tr_stmt c map sfalse nfalse nd nexits nret rret ->
+ tr_condition c map nil a ns ntrue nfalse ->
+ tr_stmt c map (Sifthenelse a strue sfalse) ns nd nexits nret rret
+ | tr_Sloop: forall sbody ns nd nexits nret rret nloop,
+ tr_stmt c map sbody ns nloop nexits nret rret ->
+ c!nloop = Some(Inop ns) ->
+ tr_stmt c map (Sloop sbody) ns nd nexits nret rret
+ | tr_Sblock: forall sbody ns nd nexits nret rret,
+ tr_stmt c map sbody ns nd (nd :: nexits) nret rret ->
+ tr_stmt c map (Sblock sbody) ns nd nexits nret rret
+ | tr_Sexit: forall n ns nd nexits nret rret,
+ nth_error nexits n = Some ns ->
+ tr_stmt c map (Sexit n) ns nd nexits nret rret
+ | tr_Sswitch: forall a cases default ns nd nexits nret rret n r t,
+ validate_switch default cases t = true ->
+ tr_expr c map nil a ns n r ->
+ tr_switch c r nexits t n ->
+ tr_stmt c map (Sswitch a cases default) ns nd nexits nret rret
+ | tr_Sreturn_none: forall nret nd nexits,
+ tr_stmt c map (Sreturn None) nret nd nexits nret None
+ | tr_Sreturn_some: forall a ns nd nexits nret rret,
+ tr_expr c map nil a ns nret rret ->
+ tr_stmt c map (Sreturn (Some a)) ns nd nexits nret (Some rret)
+ | tr_Stailcall: forall sig b cl ns nd nexits nret rret n1 rf n2 rargs,
+ tr_expr c map nil b ns n1 rf ->
+ tr_exprlist c map (rf :: nil) cl n1 n2 rargs ->
+ c!n2 = Some (Itailcall sig (inl _ rf) rargs) ->
+ tr_stmt c map (Stailcall sig b cl) ns nd nexits nret rret.
+
+(** [tr_function f tf] specifies the RTL function [tf] that
+ [RTLgen.transl_function] returns. *)
+
+Inductive tr_function: CminorSel.function -> RTL.function -> Prop :=
+ | tr_function_intro:
+ forall f code rparams map1 s1 rvars map2 s2 nentry nret rret orret nextnode wfcode,
+ add_vars init_mapping f.(CminorSel.fn_params) init_state = OK (rparams, map1) s1 ->
+ add_vars map1 f.(CminorSel.fn_vars) s1 = OK (rvars, map2) s2 ->
+ orret = ret_reg f.(CminorSel.fn_sig) rret ->
+ tr_stmt code map2 f.(CminorSel.fn_body) nentry nret nil nret orret ->
+ code!nret = Some(Ireturn orret) ->
+ tr_function f (RTL.mkfunction
+ f.(CminorSel.fn_sig)
+ rparams
+ f.(CminorSel.fn_stackspace)
+ code
+ nentry
+ nextnode
+ wfcode).
+
+(** * Correctness proof of the translation functions *)
+
+(** We now show that the translation functions in module [RTLgen]
+ satisfy the specifications given above as inductive predicates. *)
+
+Scheme tr_expr_ind3 := Minimality for tr_expr Sort Prop
+ with tr_condition_ind3 := Minimality for tr_condition Sort Prop
+ with tr_exprlist_ind3 := Minimality for tr_exprlist Sort Prop.
+
+Definition tr_expr_condition_exprlist_ind3
+ (c: code)
+ (P : mapping -> list reg -> expr -> node -> node -> reg -> Prop)
+ (P0 : mapping -> list reg -> condexpr -> node -> node -> node -> Prop)
+ (P1 : mapping -> list reg -> exprlist -> node -> node -> list reg -> Prop) :=
+ fun a b c' d e f g h i j k l m n o =>
+ conj (tr_expr_ind3 c P P0 P1 a b c' d e f g h i j k l m n o)
+ (conj (tr_condition_ind3 c P P0 P1 a b c' d e f g h i j k l m n o)
+ (tr_exprlist_ind3 c P P0 P1 a b c' d e f g h i j k l m n o)).
+
+Lemma tr_move_extends:
+ forall s1 s2, state_extends s1 s2 ->
+ forall ns rs nd rd,
+ tr_move s1.(st_code) ns rs nd rd ->
+ tr_move s2.(st_code) ns rs nd rd.
+Proof.
+ induction 2; econstructor; eauto.
+ eapply instr_at_extends; eauto.
+Qed.
+
+Lemma tr_expr_condition_exprlist_extends:
+ forall s1 s2, state_extends s1 s2 ->
+ (forall map pr a ns nd rd,
+ tr_expr s1.(st_code) map pr a ns nd rd ->
+ tr_expr s2.(st_code) map pr a ns nd rd)
+/\(forall map pr a ns ntrue nfalse,
+ tr_condition s1.(st_code) map pr a ns ntrue nfalse ->
+ tr_condition s2.(st_code) map pr a ns ntrue nfalse)
+/\(forall map pr al ns nd rl,
+ tr_exprlist s1.(st_code) map pr al ns nd rl ->
+ tr_exprlist s2.(st_code) map pr al ns nd rl).
+Proof.
+ intros s1 s2 EXT.
+ pose (AT := fun pc i => instr_at_extends s1 s2 pc i EXT).
+ apply tr_expr_condition_exprlist_ind3; intros; econstructor; eauto.
+ eapply tr_move_extends; eauto.
+ eapply tr_move_extends; eauto.
+Qed.
+
+Lemma tr_expr_incr:
+ forall s1 s2, state_incr s1 s2 ->
+ forall map pr a ns nd rd,
+ tr_expr s1.(st_code) map pr a ns nd rd ->
+ tr_expr s2.(st_code) map pr a ns nd rd.
+Proof.
+ intros.
+ exploit tr_expr_condition_exprlist_extends.
+ apply state_incr_extends; eauto. intros [A [B C]]. eauto.
+Qed.
+
+Lemma tr_condition_incr:
+ forall s1 s2, state_incr s1 s2 ->
+ forall map pr a ns ntrue nfalse,
+ tr_condition s1.(st_code) map pr a ns ntrue nfalse ->
+ tr_condition s2.(st_code) map pr a ns ntrue nfalse.
+Proof.
+ intros.
+ exploit tr_expr_condition_exprlist_extends.
+ apply state_incr_extends; eauto. intros [A [B C]]. eauto.
+Qed.
+
+Lemma tr_exprlist_incr:
+ forall s1 s2, state_incr s1 s2 ->
+ forall map pr al ns nd rl,
+ tr_exprlist s1.(st_code) map pr al ns nd rl ->
+ tr_exprlist s2.(st_code) map pr al ns nd rl.
+Proof.
+ intros.
+ exploit tr_expr_condition_exprlist_extends.
+ apply state_incr_extends; eauto. intros [A [B C]]. eauto.
+Qed.
+
+Scheme expr_ind3 := Induction for expr Sort Prop
+ with condexpr_ind3 := Induction for condexpr Sort Prop
+ with exprlist_ind3 := Induction for exprlist Sort Prop.
+
+Definition expr_condexpr_exprlist_ind
+ (P1: expr -> Prop) (P2: condexpr -> Prop) (P3: exprlist -> Prop) :=
+ fun a b c d e f g h i j k l m n o =>
+ conj (expr_ind3 P1 P2 P3 a b c d e f g h i j k l m n o)
+ (conj (condexpr_ind3 P1 P2 P3 a b c d e f g h i j k l m n o)
+ (exprlist_ind3 P1 P2 P3 a b c d e f g h i j k l m n o)).
+
+Lemma add_move_charact:
+ forall s ns rs nd rd s',
+ add_move rs rd nd s = OK ns s' ->
+ tr_move s'.(st_code) ns rs nd rd /\ state_incr s s'.
+Proof.
+ intros. unfold add_move in H. destruct (Reg.eq rs rd).
+ inv H. split. constructor. auto with rtlg.
+ split. constructor. eauto with rtlg. eauto with rtlg.
+Qed.
+
+Lemma transl_expr_condexpr_list_charact:
+ (forall a map rd nd s ns s' pr
+ (TR: transl_expr map a rd nd s = OK ns s')
+ (WF: map_valid map s)
+ (OK: target_reg_ok map pr a rd)
+ (VALID: regs_valid pr s)
+ (VALID2: reg_valid rd s),
+ tr_expr s'.(st_code) map pr a ns nd rd
+ /\ state_incr s s')
+/\
+ (forall a map ntrue nfalse s ns s' pr
+ (TR: transl_condition map a ntrue nfalse s = OK ns s')
+ (WF: map_valid map s)
+ (VALID: regs_valid pr s),
+ tr_condition s'.(st_code) map pr a ns ntrue nfalse
+ /\ state_incr s s')
+/\
+ (forall al map rl nd s ns s' pr
+ (TR: transl_exprlist map al rl nd s = OK ns s')
+ (WF: map_valid map s)
+ (OK: target_regs_ok map pr al rl)
+ (VALID1: regs_valid pr s)
+ (VALID2: regs_valid rl s),
+ tr_exprlist s'.(st_code) map pr al ns nd rl
+ /\ state_incr s s').
+Proof.
+ apply expr_condexpr_exprlist_ind; intros; try (monadInv TR).
+ (* Evar *)
+ generalize EQ; unfold find_var. caseEq (map_vars map)!i; intros; inv EQ1.
+ exploit add_move_charact; eauto.
+ intros [A B].
+ split. econstructor; eauto.
+ inv OK. left; congruence. right; eauto.
+ auto.
+ (* Eop *)
+ inv OK.
+ exploit (H _ _ _ _ _ _ pr EQ2); eauto with rtlg. intros [A B].
+ split. econstructor; eauto.
+ eapply instr_at_incr; eauto.
+ apply state_incr_trans with s1; eauto with rtlg.
+ (* Eload *)
+ inv OK.
+ exploit (H _ _ _ _ _ _ pr EQ2); eauto with rtlg. intros [A B].
+ split. econstructor; eauto.
+ eapply instr_at_incr; eauto.
+ apply state_incr_trans with s1; eauto with rtlg.
+ (* Estore *)
+ inv OK.
+ assert (state_incr s s1). eauto with rtlg.
+ exploit (H0 _ _ _ _ _ _ (x ++ pr) EQ0).
+ eauto with rtlg.
+ apply target_reg_ok_append. constructor; auto.
+ intros. exploit alloc_regs_fresh_or_in_map; eauto.
+ intros [A|B]. auto. right. apply sym_not_equal.
+ eapply valid_fresh_different; eauto with rtlg.
+ red; intros. elim (in_app_or _ _ _ H4); intro.
+ exploit alloc_regs_valid; eauto with rtlg.
+ generalize (VALID _ H5). eauto with rtlg.
+ eauto with rtlg.
+ intros [A B].
+ exploit (H _ _ _ _ _ _ pr EQ3); eauto with rtlg.
+ intros [C D].
+ split. econstructor; eauto.
+ apply tr_expr_incr with s2; eauto with rtlg.
+ apply instr_at_incr with s1; eauto with rtlg.
+ eauto with rtlg.
+ (* Ecall *)
+ inv OK.
+ assert (state_incr s0 s3).
+ apply state_incr_trans with s1. eauto with rtlg.
+ apply state_incr_trans with s2; eauto with rtlg.
+ assert (regs_valid (x :: pr) s1).
+ apply regs_valid_cons; eauto with rtlg.
+ exploit (H0 _ _ _ _ _ _ (x :: pr) EQ2).
+ eauto with rtlg.
+ apply alloc_regs_target_ok with s1 s2; eauto with rtlg.
+ eauto with rtlg.
+ apply regs_valid_incr with s2; eauto with rtlg.
+ intros [A B].
+ exploit (H _ _ _ _ _ _ pr EQ4).
+ eauto with rtlg.
+ eauto with rtlg.
+ apply regs_valid_incr with s0; eauto with rtlg.
+ apply reg_valid_incr with s1; eauto with rtlg.
+ intros [C D].
+ split. econstructor; eauto.
+ apply tr_exprlist_incr with s4; eauto.
+ apply instr_at_incr with s3; eauto with rtlg.
+ eauto with rtlg.
+ (* Econdition *)
+ inv OK.
+ exploit (H1 _ _ _ _ _ _ pr EQ); eauto with rtlg.
+ constructor; auto.
+ intros [A B].
+ exploit (H0 _ _ _ _ _ _ pr EQ1); eauto with rtlg.
+ constructor; auto.
+ intros [C D].
+ exploit (H _ _ _ _ _ _ pr EQ2); eauto with rtlg.
+ intros [E F].
+ split. econstructor; eauto.
+ apply tr_expr_incr with s1; auto.
+ apply tr_expr_incr with s0; eauto with rtlg.
+ apply state_incr_trans with s0; auto.
+ apply state_incr_trans with s1; auto.
+ (* Elet *)
+ inv OK.
+ exploit (H0 _ _ _ _ _ _ pr EQ1).
+ apply add_letvar_valid; eauto with rtlg.
+ constructor; auto.
+ red; unfold reg_in_map. simpl. intros [[id A] | [B | C]].
+ elim H1. left; exists id; auto.
+ subst x. apply valid_fresh_absurd with rd s. auto. eauto with rtlg.
+ elim H1. right; auto.
+ eauto with rtlg. eauto with rtlg.
+ intros [A B].
+ exploit (H _ _ _ _ _ _ pr EQ2); eauto with rtlg. intros [C D].
+ split. econstructor.
+ eapply new_reg_not_in_map; eauto with rtlg. eauto.
+ apply tr_expr_incr with s1; auto.
+ eauto with rtlg.
+ (* Eletvar *)
+ generalize EQ; unfold find_letvar. caseEq (nth_error (map_letvars map) n); intros; inv EQ0.
+ monadInv EQ1.
+ exploit add_move_charact; eauto.
+ intros [A B].
+ split. econstructor; eauto.
+ inv OK. left; congruence. right; eauto.
+ auto.
+ monadInv EQ1.
+ (* Ealloc *)
+ inv OK.
+ exploit (H _ _ _ _ _ _ pr EQ2); eauto with rtlg.
+ intros [A B].
+ split. econstructor; eauto.
+ eapply instr_at_incr; eauto.
+ apply state_incr_trans with s1; eauto with rtlg.
+
+ (* CEtrue *)
+ split. constructor. auto with rtlg.
+ (* CEfalse *)
+ split. constructor. auto with rtlg.
+ (* CEcond *)
+ exploit (H _ _ _ _ _ _ pr EQ2); eauto with rtlg.
+ intros [A B].
+ split. econstructor; eauto.
+ apply instr_at_incr with s1; eauto with rtlg.
+ eauto with rtlg.
+ (* CEcondition *)
+ exploit (H1 _ _ _ _ _ _ pr EQ); eauto with rtlg.
+ intros [A B].
+ exploit (H0 _ _ _ _ _ _ pr EQ1); eauto with rtlg.
+ intros [C D].
+ exploit (H _ _ _ _ _ _ pr EQ2); eauto with rtlg.
+ intros [E F].
+ split. econstructor; eauto.
+ apply tr_condition_incr with s1; eauto with rtlg.
+ apply tr_condition_incr with s0; eauto with rtlg.
+ eauto with rtlg.
+
+ (* Enil *)
+ destruct rl; inv TR. split. constructor. eauto with rtlg.
+ (* Econs *)
+ destruct rl; simpl in TR; monadInv TR. inv OK.
+ exploit H0; eauto.
+ apply regs_valid_cons. apply VALID2. auto with coqlib. auto.
+ red; intros; apply VALID2; auto with coqlib.
+ intros [A B].
+ exploit H; eauto.
+ eauto with rtlg.
+ eauto with rtlg.
+ generalize (VALID2 r (in_eq _ _)). eauto with rtlg.
+ intros [C D].
+ split. econstructor; eauto.
+ apply tr_exprlist_incr with s0; auto.
+ apply state_incr_trans with s0; eauto with rtlg.
+Qed.
+
+Lemma transl_expr_charact:
+ forall a map rd nd s ns s'
+ (TR: transl_expr map a rd nd s = OK ns s')
+ (WF: map_valid map s)
+ (OK: target_reg_ok map nil a rd)
+ (VALID2: reg_valid rd s),
+ tr_expr s'.(st_code) map nil a ns nd rd
+ /\ state_incr s s'.
+Proof.
+ destruct transl_expr_condexpr_list_charact as [A [B C]].
+ intros. eapply A; eauto with rtlg.
+Qed.
+
+Lemma transl_condexpr_charact:
+ forall a map ntrue nfalse s ns s'
+ (TR: transl_condition map a ntrue nfalse s = OK ns s')
+ (WF: map_valid map s),
+ tr_condition s'.(st_code) map nil a ns ntrue nfalse
+ /\ state_incr s s'.
+Proof.
+ destruct transl_expr_condexpr_list_charact as [A [B C]].
+ intros. eapply B; eauto with rtlg.
+Qed.
+
+Lemma tr_switch_extends:
+ forall s1 s2, state_extends s1 s2 ->
+ forall r nexits t ns,
+ tr_switch s1.(st_code) r nexits t ns ->
+ tr_switch s2.(st_code) r nexits t ns.
+Proof.
+ induction 2; econstructor; eauto with rtlg.
+ eapply instr_at_extends; eauto.
+ eapply instr_at_extends; eauto.
+Qed.
+
+Lemma tr_stmt_extends:
+ forall s1 s2, state_extends s1 s2 ->
+ forall map s ns nd nexits nret rret,
+ tr_stmt s1.(st_code) map s ns nd nexits nret rret ->
+ tr_stmt s2.(st_code) map s ns nd nexits nret rret.
+Proof.
+ intros s1 s2 EXT.
+ destruct (tr_expr_condition_exprlist_extends s1 s2 EXT) as [A [B C]].
+ pose (AT := fun pc i => instr_at_extends s1 s2 pc i EXT).
+ induction 1; econstructor; eauto.
+ eapply tr_move_extends; eauto.
+ eapply tr_switch_extends; eauto.
+Qed.
+
+Lemma tr_stmt_incr:
+ forall s1 s2, state_incr s1 s2 ->
+ forall map s ns nd nexits nret rret,
+ tr_stmt s1.(st_code) map s ns nd nexits nret rret ->
+ tr_stmt s2.(st_code) map s ns nd nexits nret rret.
+Proof.
+ intros. eapply tr_stmt_extends; eauto with rtlg.
+Qed.
+
+Lemma transl_exit_charact:
+ forall nexits n s ne s',
+ transl_exit nexits n s = OK ne s' ->
+ nth_error nexits n = Some ne /\ s' = s.
+Proof.
+ intros until s'. unfold transl_exit.
+ destruct (nth_error nexits n); intro; monadInv H. auto.
+Qed.
+
+Lemma transl_switch_charact:
+ forall r nexits t s ns s',
+ transl_switch r nexits t s = OK ns s' ->
+ tr_switch s'.(st_code) r nexits t ns /\ state_incr s s'.
+Proof.
+ induction t; simpl; intros.
+ exploit transl_exit_charact; eauto. intros [A B].
+ split. econstructor; eauto. subst s'; auto with rtlg.
+
+ monadInv H.
+ exploit transl_exit_charact; eauto. intros [A B]. subst s1.
+ exploit IHt; eauto. intros [C D].
+ split. econstructor; eauto with rtlg.
+ apply tr_switch_extends with s0; eauto with rtlg.
+ eauto with rtlg.
+
+ monadInv H.
+ exploit IHt2; eauto. intros [A B].
+ exploit IHt1; eauto. intros [C D].
+ split. econstructor.
+ apply tr_switch_extends with s1; eauto with rtlg.
+ apply tr_switch_extends with s0; eauto with rtlg.
+ eauto with rtlg.
+ eauto with rtlg.
+Qed.
+
+Lemma transl_stmt_charact:
+ forall map stmt nd nexits nret rret s ns s'
+ (TR: transl_stmt map stmt nd nexits nret rret s = OK ns s')
+ (WF: map_valid map s)
+ (OK: return_reg_ok s map rret),
+ tr_stmt s'.(st_code) map stmt ns nd nexits nret rret
+ /\ state_incr s s'.
+Proof.
+ induction stmt; intros; simpl in TR; try (monadInv TR).
+ (* Sskip *)
+ split. constructor. auto with rtlg.
+ (* Sexpr *)
+ exploit transl_expr_charact; eauto with rtlg. intros [A B].
+ split. econstructor; eauto. eauto with rtlg.
+ (* Sassign *)
+ exploit add_move_charact; eauto. intros [A B].
+ exploit transl_expr_charact; eauto with rtlg.
+ apply map_valid_incr with s; eauto with rtlg.
+ intros [C D].
+ generalize EQ. unfold find_var. caseEq (map_vars map)!i; intros; inv EQ2.
+ split. econstructor; eauto.
+ apply tr_move_extends with s2; eauto with rtlg.
+ eauto with rtlg.
+ (* Sseq *)
+ exploit IHstmt2; eauto with rtlg. intros [A B].
+ exploit IHstmt1; eauto with rtlg. intros [C D].
+ split. econstructor; eauto. apply tr_stmt_incr with s0; eauto with rtlg.
+ eauto with rtlg.
+ (* Sifthenelse *)
+ destruct (more_likely c stmt1 stmt2); monadInv TR.
+ exploit IHstmt2; eauto. intros [A B].
+ exploit IHstmt1; eauto with rtlg. intros [C D].
+ exploit transl_condexpr_charact; eauto with rtlg. intros [E F].
+ split. econstructor; eauto.
+ apply tr_stmt_incr with s1; eauto with rtlg.
+ apply tr_stmt_incr with s0; eauto with rtlg.
+ eauto with rtlg.
+ exploit IHstmt1; eauto. intros [A B].
+ exploit IHstmt2; eauto with rtlg. intros [C D].
+ exploit transl_condexpr_charact; eauto with rtlg. intros [E F].
+ split. econstructor; eauto.
+ apply tr_stmt_incr with s0; eauto with rtlg.
+ apply tr_stmt_incr with s1; eauto with rtlg.
+ eauto with rtlg.
+ (* Sloop *)
+ assert (state_incr s s0).
+ eapply reserve_instr_incr; eauto.
+ exploit IHstmt; eauto with rtlg. intros [A B].
+ split. econstructor.
+ apply tr_stmt_extends with s1; eauto.
+ eapply update_instr_extends; eauto.
+ unfold update_instr in EQ0.
+ destruct (plt x (st_nextnode s1)); inv EQ0.
+ simpl. apply PTree.gss.
+ eapply update_instr_incr; eauto.
+ (* Sblock *)
+ exploit IHstmt; eauto. intros [A B].
+ split. econstructor; eauto. auto.
+ (* Sexit *)
+ exploit transl_exit_charact; eauto. intros [A B]. subst s'.
+ split. econstructor; eauto. auto with rtlg.
+ (* Sswitch *)
+ generalize TR; clear TR.
+ set (t := compile_switch n l).
+ caseEq (validate_switch n l t); intro VALID; intros.
+ monadInv TR.
+ exploit transl_switch_charact; eauto with rtlg. intros [A B].
+ exploit transl_expr_charact; eauto with rtlg. intros [C D].
+ split. econstructor; eauto with rtlg.
+ apply tr_switch_extends with s1; eauto with rtlg.
+ eauto with rtlg.
+ monadInv TR.
+ (* Sreturn *)
+ destruct o; destruct rret; inv TR.
+ inv OK.
+ exploit transl_expr_charact; eauto with rtlg.
+ constructor. auto. simpl; tauto.
+ intros [A B].
+ split. econstructor; eauto. auto.
+ split. constructor. auto with rtlg.
+ (* Stailcall *)
+ assert (state_incr s0 s2) by eauto with rtlg.
+ destruct transl_expr_condexpr_list_charact as [A [B C]].
+ exploit (C _ _ _ _ _ _ _ (x ::nil) EQ2); eauto with rtlg.
+ apply alloc_regs_target_ok with s1 s2; eauto with rtlg.
+ apply regs_valid_cons. eauto with rtlg. apply regs_valid_nil.
+ apply regs_valid_cons. apply reg_valid_incr with s1; eauto with rtlg.
+ apply regs_valid_nil.
+ apply regs_valid_incr with s2; eauto with rtlg.
+ intros [D E].
+ exploit (A _ _ _ _ _ _ _ nil EQ4); eauto with rtlg.
+ apply reg_valid_incr with s1; eauto with rtlg.
+ intros [F G].
+ split. econstructor; eauto.
+ apply tr_exprlist_incr with s4; eauto.
+ apply instr_at_incr with s3; eauto with rtlg.
+ eauto with rtlg.
+Qed.
+
+Lemma transl_function_charact:
+ forall f tf,
+ transl_function f = Errors.OK tf ->
+ tr_function f tf.
+Proof.
+ intros until tf. unfold transl_function.
+ caseEq (transl_fun f init_state). congruence.
+ intros [nentry rparams] sfinal TR E. inv E.
+ monadInv TR.
+ exploit add_vars_valid. eexact EQ. apply init_mapping_valid.
+ intros [A B].
+ exploit add_vars_valid. eexact EQ1. auto.
+ intros [C D].
+ exploit transl_stmt_charact; eauto with rtlg.
+ unfold ret_reg. destruct (sig_res (CminorSel.fn_sig f)).
+ constructor. eauto with rtlg. eauto with rtlg.
+ constructor.
+ intros [E F].
+ eapply tr_function_intro; eauto with rtlg.
+ apply instr_at_incr with s2; eauto with rtlg.
+Qed.
diff --git a/backend/RTLtyping.v b/backend/RTLtyping.v
index 97d063a..4056749 100644
--- a/backend/RTLtyping.v
+++ b/backend/RTLtyping.v
@@ -1,6 +1,7 @@
(** Typing rules and a type inference algorithm for RTL. *)
Require Import Coqlib.
+Require Import Errors.
Require Import Maps.
Require Import AST.
Require Import Op.
@@ -22,15 +23,17 @@ Require Conventions.
enabling each pseudo-register to be mapped to a single hardware register
or stack location of the correct type.
-
- The typing judgement for instructions is of the form [wt_instr f env instr],
- where [f] is the current function (used to type-check [Ireturn]
- instructions) and [env] is a typing environment associating types to
- pseudo-registers. Since pseudo-registers have unique types throughout
- the function, the typing environment does not change during type-checking
- of individual instructions. One point to note is that we have two
- polymorphic operators, [Omove] and [Oundef], which can work both
- over integers and floats.
+ Finally, we also check that the successors of instructions
+ are valid, i.e. refer to non-empty nodes in the CFG.
+
+ The typing judgement for instructions is of the form [wt_instr f env
+ instr], where [f] is the current function (used to type-check
+ [Ireturn] instructions) and [env] is a typing environment
+ associating types to pseudo-registers. Since pseudo-registers have
+ unique types throughout the function, the typing environment does
+ not change during type-checking of individual instructions. One
+ point to note is that we have one polymorphic operator, [Omove],
+ which can work over both integers and floats.
*)
Definition regenv := reg -> typ.
@@ -38,51 +41,67 @@ Definition regenv := reg -> typ.
Section WT_INSTR.
Variable env: regenv.
-Variable funsig: signature.
+Variable funct: function.
+
+Definition valid_successor (s: node) : Prop :=
+ exists i, funct.(fn_code)!s = Some i.
Inductive wt_instr : instruction -> Prop :=
| wt_Inop:
forall s,
+ valid_successor s ->
wt_instr (Inop s)
| wt_Iopmove:
forall r1 r s,
env r1 = env r ->
+ valid_successor s ->
wt_instr (Iop Omove (r1 :: nil) r s)
- | wt_Iopundef:
- forall r s,
- wt_instr (Iop Oundef nil r s)
| wt_Iop:
forall op args res s,
- op <> Omove -> op <> Oundef ->
+ op <> Omove ->
(List.map env args, env res) = type_of_operation op ->
+ valid_successor s ->
wt_instr (Iop op args res s)
| wt_Iload:
forall chunk addr args dst s,
List.map env args = type_of_addressing addr ->
env dst = type_of_chunk chunk ->
+ valid_successor s ->
wt_instr (Iload chunk addr args dst s)
| wt_Istore:
forall chunk addr args src s,
List.map env args = type_of_addressing addr ->
env src = type_of_chunk chunk ->
+ valid_successor s ->
wt_instr (Istore chunk addr args src s)
| wt_Icall:
forall sig ros args res s,
match ros with inl r => env r = Tint | inr s => True end ->
List.map env args = sig.(sig_args) ->
- env res = match sig.(sig_res) with None => Tint | Some ty => ty end ->
+ env res = proj_sig_res sig ->
+ valid_successor s ->
wt_instr (Icall sig ros args res s)
+ | wt_Itailcall:
+ forall sig ros args,
+ match ros with inl r => env r = Tint | inr s => True end ->
+ sig.(sig_res) = funct.(fn_sig).(sig_res) ->
+ List.map env args = sig.(sig_args) ->
+ Conventions.tailcall_possible sig ->
+ wt_instr (Itailcall sig ros args)
| wt_Ialloc:
forall arg res s,
env arg = Tint -> env res = Tint ->
+ valid_successor s ->
wt_instr (Ialloc arg res s)
| wt_Icond:
forall cond args s1 s2,
List.map env args = type_of_condition cond ->
+ valid_successor s1 ->
+ valid_successor s2 ->
wt_instr (Icond cond args s1 s2)
| wt_Ireturn:
forall optres,
- option_map env optres = funsig.(sig_res) ->
+ option_map env optres = funct.(fn_sig).(sig_res) ->
wt_instr (Ireturn optres).
End WT_INSTR.
@@ -90,7 +109,7 @@ End WT_INSTR.
(** A function [f] is well-typed w.r.t. a typing environment [env],
written [wt_function env f], if all instructions are well-typed,
parameters agree in types with the function signature, and
- names of parameters are pairwise distinct. *)
+ parameters are pairwise distinct. *)
Record wt_function (f: function) (env: regenv): Prop :=
mk_wt_function {
@@ -100,7 +119,9 @@ Record wt_function (f: function) (env: regenv): Prop :=
list_norepet f.(fn_params);
wt_instrs:
forall pc instr,
- f.(fn_code)!pc = Some instr -> wt_instr env f.(fn_sig) instr
+ f.(fn_code)!pc = Some instr -> wt_instr env f instr;
+ wt_entrypoint:
+ valid_successor f f.(fn_entrypoint)
}.
Inductive wt_fundef: fundef -> Prop :=
@@ -142,6 +163,9 @@ Variable env: regenv.
Lemma typ_eq: forall (t1 t2: typ), {t1=t2} + {t1<>t2}.
Proof. decide equality. Qed.
+Lemma opt_typ_eq: forall (t1 t2: option typ), {t1=t2} + {t1<>t2}.
+Proof. decide equality. apply typ_eq. Qed.
+
Definition check_reg (r: reg) (ty: typ): bool :=
if typ_eq (env r) ty then true else false.
@@ -156,34 +180,47 @@ Definition check_op (op: operation) (args: list reg) (res: reg): bool :=
let (targs, tres) := type_of_operation op in
check_regs args targs && check_reg res tres.
+Definition check_successor (s: node) : bool :=
+ match funct.(fn_code)!s with None => false | Some i => true end.
+
Definition check_instr (i: instruction) : bool :=
match i with
- | Inop _ =>
- true
- | Iop Omove (arg::nil) res _ =>
- if typ_eq (env arg) (env res) then true else false
- | Iop Omove args res _ =>
- false
- | Iop Oundef nil res _ =>
- true
- | Iop Oundef args res _ =>
+ | Inop s =>
+ check_successor s
+ | Iop Omove (arg::nil) res s =>
+ if typ_eq (env arg) (env res)
+ then check_successor s
+ else false
+ | Iop Omove args res s =>
false
- | Iop op args res _ =>
- check_op op args res
- | Iload chunk addr args dst _ =>
+ | Iop op args res s =>
+ check_op op args res && check_successor s
+ | Iload chunk addr args dst s =>
check_regs args (type_of_addressing addr)
&& check_reg dst (type_of_chunk chunk)
- | Istore chunk addr args src _ =>
+ && check_successor s
+ | Istore chunk addr args src s =>
check_regs args (type_of_addressing addr)
&& check_reg src (type_of_chunk chunk)
- | Icall sig ros args res _ =>
+ && check_successor s
+ | Icall sig ros args res s =>
+ match ros with inl r => check_reg r Tint | inr s => true end
+ && check_regs args sig.(sig_args)
+ && check_reg res (proj_sig_res sig)
+ && check_successor s
+ | Itailcall sig ros args =>
match ros with inl r => check_reg r Tint | inr s => true end
&& check_regs args sig.(sig_args)
- && check_reg res (match sig.(sig_res) with None => Tint | Some ty => ty end)
- | Ialloc arg res _ =>
- check_reg arg Tint && check_reg res Tint
- | Icond cond args _ _ =>
+ && opt_typ_eq sig.(sig_res) funct.(fn_sig).(sig_res)
+ && zeq (Conventions.size_arguments sig) 14
+ | Ialloc arg res s =>
+ check_reg arg Tint
+ && check_reg res Tint
+ && check_successor s
+ | Icond cond args s1 s2 =>
check_regs args (type_of_condition cond)
+ && check_successor s1
+ && check_successor s2
| Ireturn optres =>
match optres, funct.(fn_sig).(sig_res) with
| None, None => true
@@ -203,6 +240,14 @@ Fixpoint check_instrs (instrs: list (node * instruction)) : bool :=
(** ** Correctness of the type-checking algorithm *)
+Ltac elimAndb :=
+ match goal with
+ | [ H: _ && _ = true |- _ ] =>
+ elim (andb_prop _ _ H); clear H; intros; elimAndb
+ | _ =>
+ idtac
+ end.
+
Lemma check_reg_correct:
forall r ty, check_reg r ty = true -> env r = ty.
Proof.
@@ -215,8 +260,8 @@ Lemma check_regs_correct:
Proof.
induction rl; destruct tyl; simpl; intros.
auto. discriminate. discriminate.
- elim (andb_prop _ _ H); intros.
- rewrite (check_reg_correct _ _ H0). rewrite (IHrl tyl H1). auto.
+ elimAndb.
+ rewrite (check_reg_correct _ _ H). rewrite (IHrl tyl H0). auto.
Qed.
Lemma check_op_correct:
@@ -225,45 +270,65 @@ Lemma check_op_correct:
(List.map env args, env res) = type_of_operation op.
Proof.
unfold check_op; intros.
- destruct (type_of_operation op) as [targs tres].
- elim (andb_prop _ _ H); intros.
- rewrite (check_regs_correct _ _ H0).
- rewrite (check_reg_correct _ _ H1).
+ destruct (type_of_operation op) as [targs tres].
+ elimAndb.
+ rewrite (check_regs_correct _ _ H).
+ rewrite (check_reg_correct _ _ H0).
auto.
Qed.
+Lemma check_successor_correct:
+ forall s,
+ check_successor s = true -> valid_successor funct s.
+Proof.
+ intro; unfold check_successor, valid_successor.
+ destruct (fn_code funct)!s; intro.
+ exists i; auto.
+ discriminate.
+Qed.
+
Lemma check_instr_correct:
- forall i, check_instr i = true -> wt_instr env funct.(fn_sig) i.
+ forall i, check_instr i = true -> wt_instr env funct i.
Proof.
- unfold check_instr; intros; destruct i.
+ unfold check_instr; intros; destruct i; elimAndb.
(* nop *)
- constructor.
+ constructor. apply check_successor_correct; auto.
(* op *)
- destruct o;
- try (apply wt_Iop; [congruence|congruence|apply check_op_correct;auto]).
+ destruct o; elimAndb;
+ try (apply wt_Iop; [ congruence
+ | apply check_op_correct; auto
+ | apply check_successor_correct; auto ]).
destruct l; try discriminate. destruct l; try discriminate.
destruct (typ_eq (env r0) (env r)); try discriminate.
- apply wt_Iopmove; auto.
- destruct l; try discriminate.
- apply wt_Iopundef.
+ apply wt_Iopmove; auto. apply check_successor_correct; auto.
(* load *)
- elim (andb_prop _ _ H); intros.
constructor. apply check_regs_correct; auto. apply check_reg_correct; auto.
+ apply check_successor_correct; auto.
(* store *)
- elim (andb_prop _ _ H); intros.
constructor. apply check_regs_correct; auto. apply check_reg_correct; auto.
+ apply check_successor_correct; auto.
(* call *)
- elim (andb_prop _ _ H); clear H; intros.
- elim (andb_prop _ _ H); clear H; intros.
constructor.
destruct s0; auto. apply check_reg_correct; auto.
apply check_regs_correct; auto.
apply check_reg_correct; auto.
+ apply check_successor_correct; auto.
+ (* tailcall *)
+ constructor.
+ destruct s0; auto. apply check_reg_correct; auto.
+ eapply proj_sumbool_true; eauto.
+ apply check_regs_correct; auto.
+ rewrite Conventions.tailcall_possible_size.
+ eapply proj_sumbool_true; eauto.
(* alloc *)
- elim (andb_prop _ _ H); intros.
- constructor; apply check_reg_correct; auto.
+ constructor.
+ apply check_reg_correct; auto.
+ apply check_reg_correct; auto.
+ apply check_successor_correct; auto.
(* cond *)
constructor. apply check_regs_correct; auto.
+ apply check_successor_correct; auto.
+ apply check_successor_correct; auto.
(* return *)
constructor.
destruct o; simpl; destruct funct.(fn_sig).(sig_res); try discriminate.
@@ -274,11 +339,11 @@ Qed.
Lemma check_instrs_correct:
forall instrs,
check_instrs instrs = true ->
- forall pc i, In (pc, i) instrs -> wt_instr env funct.(fn_sig) i.
+ forall pc i, In (pc, i) instrs -> wt_instr env funct i.
Proof.
induction instrs; simpl; intros.
elim H0.
- destruct a as [pc' i']. elim (andb_prop _ _ H); clear H; intros.
+ destruct a as [pc' i']. elimAndb.
elim H0; intro.
inversion H2; subst pc' i'. apply check_instr_correct; auto.
eauto.
@@ -288,20 +353,24 @@ End TYPECHECKING.
(** ** The type inference function **)
-Definition type_function (f: function): option regenv :=
+Open Scope string_scope.
+
+Definition type_function (f: function): res regenv :=
let instrs := PTree.elements f.(fn_code) in
match infer_type_environment f instrs with
- | None => None
+ | None => Error (msg "RTL type inference error")
| Some env =>
if check_regs env f.(fn_params) f.(fn_sig).(sig_args)
&& check_params_norepet f.(fn_params)
&& check_instrs f env instrs
- then Some env else None
+ && check_successor f f.(fn_entrypoint)
+ then OK env
+ else Error (msg "RTL type checking error")
end.
Lemma type_function_correct:
forall f env,
- type_function f = Some env ->
+ type_function f = OK env ->
wt_function f env.
Proof.
unfold type_function; intros until env.
@@ -311,6 +380,7 @@ Proof.
caseEq (check_regs env' f.(fn_params) f.(fn_sig).(sig_args)); intro; simpl; try congruence.
caseEq (check_params_norepet f.(fn_params)); intro; simpl; try congruence.
caseEq (check_instrs f env' instrs); intro; simpl; try congruence.
+ caseEq (check_successor f (fn_entrypoint f)); intro; simpl; try congruence.
intro EQ; inversion EQ; subst env'.
constructor.
apply check_regs_correct; auto.
@@ -318,6 +388,7 @@ Proof.
destruct (list_norepet_dec Reg.eq (fn_params f)). auto. discriminate.
intros. eapply check_instrs_correct. eauto.
unfold instrs. apply PTree.elements_correct. eauto.
+ apply check_successor_correct. auto.
congruence.
Qed.
@@ -330,7 +401,8 @@ Qed.
property: if the execution does not fail because of a failed run-time
test, the result values and register states match the static
typing assumptions. This preservation property will be useful
- later for the proof of semantic equivalence between [Machabstr] and [Mach].
+ later for the proof of semantic equivalence between
+ [Machabstr] and [Machconcr].
Even though we do not need it for [RTL], we show preservation for [RTL]
here, as a warm-up exercise and because some of the lemmas will be
useful later. *)
@@ -340,6 +412,7 @@ Require Import Values.
Require Import Mem.
Require Import Integers.
Require Import Events.
+Require Import Smallstep.
Definition wt_regset (env: regenv) (rs: regset) : Prop :=
forall r, Val.has_type (rs#r) (env r).
@@ -385,6 +458,36 @@ Proof.
induction 1. inversion H0; exact I.
Qed.
+Inductive wt_stackframes: list stackframe -> option typ -> Prop :=
+ | wt_stackframes_nil:
+ wt_stackframes nil (Some Tint)
+ | wt_stackframes_cons:
+ forall s res f sp pc rs env tyres,
+ wt_function f env ->
+ wt_regset env rs ->
+ env res = match tyres with None => Tint | Some t => t end ->
+ wt_stackframes s (sig_res (fn_sig f)) ->
+ wt_stackframes (Stackframe res (fn_code f) sp pc rs :: s) tyres.
+
+Inductive wt_state: state -> Prop :=
+ | wt_state_intro:
+ forall s f sp pc rs m env
+ (WT_STK: wt_stackframes s (sig_res (fn_sig f)))
+ (WT_FN: wt_function f env)
+ (WT_RS: wt_regset env rs),
+ wt_state (State s (fn_code f) sp pc rs m)
+ | wt_state_call:
+ forall s f args m,
+ wt_stackframes s (sig_res (funsig f)) ->
+ wt_fundef f ->
+ Val.has_type_list args (sig_args (funsig f)) ->
+ wt_state (Callstate s f args m)
+ | wt_state_return:
+ forall s v m tyres,
+ wt_stackframes s tyres ->
+ Val.has_type v (match tyres with None => Tint | Some t => t end) ->
+ wt_state (Returnstate s v m).
+
Section SUBJECT_REDUCTION.
Variable p: program.
@@ -393,90 +496,77 @@ Hypothesis wt_p: wt_program p.
Let ge := Genv.globalenv p.
-Definition exec_instr_subject_reduction
- (c: code) (sp: val)
- (pc: node) (rs: regset) (m: mem) (t: trace)
- (pc': node) (rs': regset) (m': mem) : Prop :=
- forall env f
- (CODE: c = fn_code f)
- (WT_FN: wt_function f env)
- (WT_RS: wt_regset env rs),
- wt_regset env rs'.
-
-Definition exec_function_subject_reduction
- (f: fundef) (args: list val) (m: mem) (t: trace) (res: val) (m': mem) : Prop :=
- wt_fundef f ->
- Val.has_type_list args (sig_args (funsig f)) ->
- Val.has_type res (proj_sig_res (funsig f)).
-
Lemma subject_reduction:
- forall f args m t res m',
- exec_function ge f args m t res m' ->
- exec_function_subject_reduction f args m t res m'.
+ forall st1 t st2, step ge st1 t st2 ->
+ forall (WT: wt_state st1), wt_state st2.
Proof.
- apply (exec_function_ind_3 ge
- exec_instr_subject_reduction
- exec_instr_subject_reduction
- exec_function_subject_reduction);
- intros; red; intros;
- try (rewrite CODE in H;
- generalize (wt_instrs _ _ WT_FN pc _ H);
+ induction 1; intros; inv WT;
+ try (generalize (wt_instrs _ _ WT_FN pc _ H);
intro WT_INSTR;
- inversion WT_INSTR).
-
- assumption.
-
+ inv WT_INSTR).
+ (* Inop *)
+ econstructor; eauto.
+ (* Iop *)
+ econstructor; eauto.
apply wt_regset_assign. auto.
- subst op. subst args. simpl in H0. injection H0; intro.
- subst v. rewrite <- H2. apply WT_RS.
-
- apply wt_regset_assign. auto.
- subst op; subst args; simpl in H0. injection H0; intro; subst v.
- simpl; auto.
-
+ simpl in H0. inv H0. rewrite <- H3. apply WT_RS.
+ econstructor; eauto.
apply wt_regset_assign. auto.
replace (env res) with (snd (type_of_operation op)).
- apply type_of_operation_sound with fundef ge rs##args sp; auto.
- rewrite <- H7. reflexivity.
-
+ apply type_of_operation_sound with fundef ge rs##args sp m; auto.
+ rewrite <- H6. reflexivity.
+ (* Iload *)
+ econstructor; eauto.
apply wt_regset_assign. auto. rewrite H8.
eapply type_of_chunk_correct; eauto.
-
- assumption.
-
- apply wt_regset_assign. auto. rewrite H11. rewrite <- H1.
+ (* Istore *)
+ econstructor; eauto.
+ (* Icall *)
assert (wt_fundef f).
destruct ros; simpl in H0.
pattern f. apply Genv.find_funct_prop with fundef unit p (rs#r).
exact wt_p. exact H0.
- caseEq (Genv.find_symbol ge i); intros; rewrite H12 in H0.
+ caseEq (Genv.find_symbol ge i); intros; rewrite H1 in H0.
pattern f. apply Genv.find_funct_ptr_prop with fundef unit p b.
exact wt_p. exact H0.
discriminate.
- eapply H3. auto. rewrite H1. rewrite <- H10.
- apply wt_regset_list; auto.
-
- apply wt_regset_assign. auto. rewrite H6; exact I.
-
- assumption.
- assumption.
- assumption.
- eauto.
- eauto.
-
- inversion H4; subst f0.
- assert (WT_INIT: wt_regset env (init_regs args (fn_params f))).
- apply wt_init_regs. rewrite (wt_params _ _ H7). assumption.
- generalize (H1 env f (refl_equal (fn_code f)) H7 WT_INIT).
- intro WT_RS.
- generalize (wt_instrs _ _ H7 pc _ H2).
- intro WT_INSTR; inversion WT_INSTR.
- unfold proj_sig_res; simpl.
- destruct or; simpl in H3; simpl in H8; rewrite <- H8.
- rewrite H3. apply WT_RS.
- rewrite H3. simpl; auto.
-
- simpl. eapply wt_event_match; eauto.
-Qed.
+ econstructor; eauto.
+ econstructor; eauto.
+ rewrite <- H7. apply wt_regset_list. auto.
+ (* Itailcall *)
+ assert (wt_fundef f).
+ destruct ros; simpl in H0.
+ pattern f. apply Genv.find_funct_prop with fundef unit p (rs#r).
+ exact wt_p. exact H0.
+ caseEq (Genv.find_symbol ge i); intros; rewrite H1 in H0.
+ pattern f. apply Genv.find_funct_ptr_prop with fundef unit p b.
+ exact wt_p. exact H0.
+ discriminate.
+ econstructor; eauto.
+ rewrite H5; auto.
+ rewrite <- H6. apply wt_regset_list. auto.
+ (* Ialloc *)
+ econstructor; eauto.
+ apply wt_regset_assign. auto. rewrite H6; exact I.
+ (* Icond *)
+ econstructor; eauto.
+ econstructor; eauto.
+ (* Ireturn *)
+ econstructor; eauto.
+ destruct or; simpl in *.
+ rewrite <- H1. apply WT_RS. exact I.
+ (* internal function *)
+ simpl in *. inv H5. inversion H1; subst.
+ econstructor; eauto.
+ apply wt_init_regs; auto. rewrite wt_params0; auto.
+ (* external function *)
+ simpl in *. inv H5.
+ econstructor; eauto.
+ change (Val.has_type res (proj_sig_res (ef_sig ef))).
+ eapply wt_event_match; eauto.
+ (* return *)
+ inv H1. econstructor; eauto.
+ apply wt_regset_assign; auto. congruence.
+Qed.
End SUBJECT_REDUCTION.
diff --git a/backend/Registers.v b/backend/Registers.v
index 578e4b8..e4b7b00 100644
--- a/backend/Registers.v
+++ b/backend/Registers.v
@@ -1,8 +1,9 @@
(** Pseudo-registers and register states.
- This library defines the type of pseudo-registers used in the RTL
- intermediate language, and of mappings from pseudo-registers to
- values as used in the dynamic semantics of RTL. *)
+ This library defines the type of pseudo-registers (also known as
+ "temporaries" in compiler literature) used in the RTL
+ intermediate language. We also define finite sets and finite maps
+ over pseudo-registers. *)
Require Import Coqlib.
Require Import AST.
diff --git a/backend/Reload.v b/backend/Reload.v
new file mode 100644
index 0000000..58e17ff
--- /dev/null
+++ b/backend/Reload.v
@@ -0,0 +1,211 @@
+(** Reloading, spilling, and explication of calling conventions. *)
+
+Require Import Coqlib.
+Require Import Maps.
+Require Import AST.
+Require Import Integers.
+Require Import Values.
+Require Import Globalenvs.
+Require Import Op.
+Require Import Locations.
+Require Import LTLin.
+Require Import Conventions.
+Require Import Parallelmove.
+Require Import Linear.
+
+(** * Spilling and reloading *)
+
+(** Operations in the Linear language, like those of the target processor,
+ operate only over machine registers, but not over stack slots.
+ Consider the LTLin instruction
+<<
+ r1 <- Lop(Oadd, r1 :: r2 :: nil)
+>>
+ and assume that [r1] and [r2] are assigned to stack locations [S s1]
+ and [S s2], respectively. The translated LTL code must load these
+ stack locations into temporary integer registers (this is called
+ ``reloading''), perform the [Oadd] operation over these temporaries,
+ leave the result in a temporary, then store the temporary back to
+ stack location [S s1] (this is called ``spilling''). In other term,
+ the generated Linear code has the following shape:
+<<
+ IT1 <- Lgetstack s1;
+ IT2 <- Lgetstack s2;
+ IT1 <- Lop(Oadd, IT1 :: IT2 :: nil);
+ Lsetstack s1 IT1;
+>>
+ This section provides functions that assist in choosing appropriate
+ temporaries and inserting the required spilling and reloading
+ operations. *)
+
+(** ** Allocation of temporary registers for reloading and spilling. *)
+
+(** [reg_for l] returns a machine register appropriate for working
+ over the location [l]: either the machine register [m] if [l = R m],
+ or a temporary register of [l]'s type if [l] is a stack slot. *)
+
+Definition reg_for (l: loc) : mreg :=
+ match l with
+ | R r => r
+ | S s => match slot_type s with Tint => IT1 | Tfloat => FT1 end
+ end.
+
+(** [regs_for ll] is similar, for a list of locations [ll] of length
+ at most 3. We ensure that distinct temporaries are used for
+ different elements of [ll]. *)
+
+Fixpoint regs_for_rec (locs: list loc) (itmps ftmps: list mreg)
+ {struct locs} : list mreg :=
+ match locs, itmps, ftmps with
+ | l1 :: ls, it1 :: its, ft1 :: fts =>
+ match l1 with
+ | R r => r
+ | S s => match slot_type s with Tint => it1 | Tfloat => ft1 end
+ end
+ :: regs_for_rec ls its fts
+ | _, _, _ => nil
+ end.
+
+Definition regs_for (locs: list loc) :=
+ regs_for_rec locs (IT1 :: IT2 :: IT3 :: nil) (FT1 :: FT2 :: FT3 :: nil).
+
+(** ** Insertion of Linear reloads, stores and moves *)
+
+(** [add_spill src dst k] prepends to [k] the instructions needed
+ to assign location [dst] the value of machine register [mreg]. *)
+
+Definition add_spill (src: mreg) (dst: loc) (k: code) :=
+ match dst with
+ | R rd => if mreg_eq src rd then k else Lop Omove (src :: nil) rd :: k
+ | S sl => Lsetstack src sl :: k
+ end.
+
+(** [add_reload src dst k] prepends to [k] the instructions needed
+ to assign machine register [mreg] the value of the location [src]. *)
+
+Definition add_reload (src: loc) (dst: mreg) (k: code) :=
+ match src with
+ | R rs => if mreg_eq rs dst then k else Lop Omove (rs :: nil) dst :: k
+ | S sl => Lgetstack sl dst :: k
+ end.
+
+(** [add_reloads] is similar for a list of locations (as sources)
+ and a list of machine registers (as destinations). *)
+
+Fixpoint add_reloads (srcs: list loc) (dsts: list mreg) (k: code)
+ {struct srcs} : code :=
+ match srcs, dsts with
+ | s1 :: sl, t1 :: tl => add_reload s1 t1 (add_reloads sl tl k)
+ | _, _ => k
+ end.
+
+(** [add_move src dst k] prepends to [k] the instructions that copy
+ the value of location [src] into location [dst]. *)
+
+Definition add_move (src dst: loc) (k: code) :=
+ if Loc.eq src dst then k else
+ match src, dst with
+ | R rs, _ =>
+ add_spill rs dst k
+ | _, R rd =>
+ add_reload src rd k
+ | S ss, S sd =>
+ let tmp :=
+ match slot_type ss with Tint => IT1 | Tfloat => FT1 end in
+ add_reload src tmp (add_spill tmp dst k)
+ end.
+
+(** [parallel_move srcs dsts k] is similar, but for a list of
+ source locations and a list of destination locations of the same
+ length. This is a parallel move, meaning that some of the
+ destinations can also occur as sources. *)
+
+Definition parallel_move (srcs dsts: list loc) (k: code) : code :=
+ List.fold_right
+ (fun p k => add_move (fst p) (snd p) k)
+ k (parmove srcs dsts).
+
+(** * Code transformation *)
+
+(** We insert appropriate reload, spill and parallel move operations
+ around each of the instructions of the source code. *)
+
+Definition transf_instr
+ (f: LTLin.function) (instr: LTLin.instruction) (k: code) : code :=
+ match instr with
+ | LTLin.Lop op args res =>
+ match is_move_operation op args with
+ | Some src =>
+ add_move src res k
+ | None =>
+ let rargs := regs_for args in
+ let rres := reg_for res in
+ add_reloads args rargs (Lop op rargs rres :: add_spill rres res k)
+ end
+ | LTLin.Lload chunk addr args dst =>
+ let rargs := regs_for args in
+ let rdst := reg_for dst in
+ add_reloads args rargs
+ (Lload chunk addr rargs rdst :: add_spill rdst dst k)
+ | LTLin.Lstore chunk addr args src =>
+ match regs_for (src :: args) with
+ | nil => nil (* never happens *)
+ | rsrc :: rargs =>
+ add_reloads (src :: args) (rsrc :: rargs)
+ (Lstore chunk addr rargs rsrc :: k)
+ end
+ | LTLin.Lcall sig los args res =>
+ let largs := loc_arguments sig in
+ let rres := loc_result sig in
+ match los with
+ | inl fn =>
+ add_reload fn IT3
+ (parallel_move args largs
+ (Lcall sig (inl _ IT3) :: add_spill rres res k))
+ | inr id =>
+ parallel_move args largs
+ (Lcall sig (inr _ id) :: add_spill rres res k)
+ end
+ | LTLin.Ltailcall sig los args =>
+ let largs := loc_arguments sig in
+ match los with
+ | inl fn =>
+ add_reload fn IT3
+ (parallel_move args largs
+ (Ltailcall sig (inl _ IT3) :: k))
+ | inr id =>
+ parallel_move args largs
+ (Ltailcall sig (inr _ id) :: k)
+ end
+ | LTLin.Lalloc arg res =>
+ add_reload arg loc_alloc_argument
+ (Lalloc :: add_spill loc_alloc_result res k)
+ | LTLin.Llabel lbl =>
+ Llabel lbl :: k
+ | LTLin.Lgoto lbl =>
+ Lgoto lbl :: k
+ | LTLin.Lcond cond args lbl =>
+ let rargs := regs_for args in
+ add_reloads args rargs (Lcond cond rargs lbl :: k)
+ | LTLin.Lreturn None =>
+ Lreturn :: k
+ | LTLin.Lreturn (Some loc) =>
+ add_reload loc (loc_result (LTLin.fn_sig f)) (Lreturn :: k)
+ end.
+
+Definition transf_code (f: LTLin.function) (c: LTLin.code) : code :=
+ List.fold_right (transf_instr f) nil c.
+
+Definition transf_function (f: LTLin.function) : function :=
+ mkfunction
+ (LTLin.fn_sig f)
+ (LTLin.fn_stacksize f)
+ (parallel_move (loc_parameters (LTLin.fn_sig f)) (LTLin.fn_params f)
+ (transf_code f (LTLin.fn_code f))).
+
+Definition transf_fundef (fd: LTLin.fundef) : Linear.fundef :=
+ transf_fundef transf_function fd.
+
+Definition transf_program (p: LTLin.program) : Linear.program :=
+ transform_program transf_fundef p.
+
diff --git a/backend/Reloadproof.v b/backend/Reloadproof.v
new file mode 100644
index 0000000..e9ced51
--- /dev/null
+++ b/backend/Reloadproof.v
@@ -0,0 +1,1230 @@
+(** Correctness proof for the [Reload] pass. *)
+
+Require Import Coqlib.
+Require Import Maps.
+Require Import AST.
+Require Import Integers.
+Require Import Values.
+Require Import Mem.
+Require Import Events.
+Require Import Globalenvs.
+Require Import Smallstep.
+Require Import Op.
+Require Import Locations.
+Require Import Conventions.
+Require Import Allocproof.
+Require Import LTLin.
+Require Import LTLintyping.
+Require Import Linear.
+Require Import Parallelmove.
+Require Import Reload.
+
+(** * Exploitation of the typing hypothesis *)
+
+(** Reloading is applied to LTLin code that is well-typed in
+ the sense of [LTLintyping]. We exploit this hypothesis to obtain information on
+ the number of arguments to operations, addressing modes and conditions. *)
+
+Remark length_type_of_condition:
+ forall (c: condition), (List.length (type_of_condition c) <= 3)%nat.
+Proof.
+ destruct c; unfold type_of_condition; simpl; omega.
+Qed.
+
+Remark length_type_of_operation:
+ forall (op: operation), (List.length (fst (type_of_operation op)) <= 3)%nat.
+Proof.
+ destruct op; unfold type_of_operation; simpl; try omega.
+ apply length_type_of_condition.
+Qed.
+
+Remark length_type_of_addressing:
+ forall (addr: addressing), (List.length (type_of_addressing addr) <= 2)%nat.
+Proof.
+ destruct addr; unfold type_of_addressing; simpl; omega.
+Qed.
+
+Lemma length_op_args:
+ forall (op: operation) (args: list loc) (res: loc),
+ (List.map Loc.type args, Loc.type res) = type_of_operation op ->
+ (List.length args <= 3)%nat.
+Proof.
+ intros. rewrite <- (list_length_map Loc.type).
+ generalize (length_type_of_operation op).
+ rewrite <- H. simpl. auto.
+Qed.
+
+Lemma length_addr_args:
+ forall (addr: addressing) (args: list loc),
+ List.map Loc.type args = type_of_addressing addr ->
+ (List.length args <= 2)%nat.
+Proof.
+ intros. rewrite <- (list_length_map Loc.type).
+ rewrite H. apply length_type_of_addressing.
+Qed.
+
+Lemma length_cond_args:
+ forall (cond: condition) (args: list loc),
+ List.map Loc.type args = type_of_condition cond ->
+ (List.length args <= 3)%nat.
+Proof.
+ intros. rewrite <- (list_length_map Loc.type).
+ rewrite H. apply length_type_of_condition.
+Qed.
+
+(** * Correctness of the Linear constructors *)
+
+(** This section proves theorems that establish the correctness of the
+ Linear constructor functions such as [add_move]. The theorems are of
+ the general form ``the generated Linear instructions execute and
+ modify the location set in the expected way: the result location(s)
+ contain the expected values; other, non-temporary locations keep
+ their values''. *)
+
+Section LINEAR_CONSTRUCTORS.
+
+Variable ge: genv.
+Variable stk: list stackframe.
+Variable f: function.
+Variable sp: val.
+
+Lemma reg_for_spec:
+ forall l,
+ R(reg_for l) = l \/ In (R (reg_for l)) temporaries.
+Proof.
+ intros. unfold reg_for. destruct l. tauto.
+ case (slot_type s); simpl; tauto.
+Qed.
+
+Lemma reg_for_diff:
+ forall l l',
+ Loc.diff l l' -> Loc.notin l' temporaries ->
+ Loc.diff (R (reg_for l)) l'.
+Proof.
+ intros. destruct (reg_for_spec l).
+ rewrite H1; auto.
+ apply Loc.diff_sym. eapply Loc.in_notin_diff; eauto.
+Qed.
+
+Lemma add_reload_correct:
+ forall src dst k rs m,
+ exists rs',
+ star step ge (State stk f sp (add_reload src dst k) rs m)
+ E0 (State stk f sp k rs' m) /\
+ rs' (R dst) = rs src /\
+ forall l, Loc.diff (R dst) l -> rs' l = rs l.
+Proof.
+ intros. unfold add_reload. destruct src.
+ case (mreg_eq m0 dst); intro.
+ subst dst. exists rs. split. apply star_refl. tauto.
+ exists (Locmap.set (R dst) (rs (R m0)) rs).
+ split. apply star_one; apply exec_Lop. reflexivity.
+ split. apply Locmap.gss.
+ intros; apply Locmap.gso; auto.
+ exists (Locmap.set (R dst) (rs (S s)) rs).
+ split. apply star_one; apply exec_Lgetstack.
+ split. apply Locmap.gss.
+ intros; apply Locmap.gso; auto.
+Qed.
+
+Lemma add_spill_correct:
+ forall src dst k rs m,
+ exists rs',
+ star step ge (State stk f sp (add_spill src dst k) rs m)
+ E0 (State stk f sp k rs' m) /\
+ rs' dst = rs (R src) /\
+ forall l, Loc.diff dst l -> rs' l = rs l.
+Proof.
+ intros. unfold add_spill. destruct dst.
+ case (mreg_eq src m0); intro.
+ subst src. exists rs. split. apply star_refl. tauto.
+ exists (Locmap.set (R m0) (rs (R src)) rs).
+ split. apply star_one. apply exec_Lop. reflexivity.
+ split. apply Locmap.gss.
+ intros; apply Locmap.gso; auto.
+ exists (Locmap.set (S s) (rs (R src)) rs).
+ split. apply star_one. apply exec_Lsetstack.
+ split. apply Locmap.gss.
+ intros; apply Locmap.gso; auto.
+Qed.
+
+Lemma add_reloads_correct_rec:
+ forall srcs itmps ftmps k rs m,
+ (List.length srcs <= List.length itmps)%nat ->
+ (List.length srcs <= List.length ftmps)%nat ->
+ (forall r, In (R r) srcs -> In r itmps -> False) ->
+ (forall r, In (R r) srcs -> In r ftmps -> False) ->
+ list_disjoint itmps ftmps ->
+ list_norepet itmps ->
+ list_norepet ftmps ->
+ exists rs',
+ star step ge
+ (State stk f sp (add_reloads srcs (regs_for_rec srcs itmps ftmps) k) rs m)
+ E0 (State stk f sp k rs' m) /\
+ reglist rs' (regs_for_rec srcs itmps ftmps) = map rs srcs /\
+ (forall r, ~(In r itmps) -> ~(In r ftmps) -> rs' (R r) = rs (R r)) /\
+ (forall s, rs' (S s) = rs (S s)).
+Proof.
+ induction srcs; simpl; intros.
+ (* base case *)
+ exists rs. split. apply star_refl. tauto.
+ (* inductive case *)
+ destruct itmps; simpl in H. omegaContradiction.
+ destruct ftmps; simpl in H0. omegaContradiction.
+ assert (R1: (length srcs <= length itmps)%nat). omega.
+ assert (R2: (length srcs <= length ftmps)%nat). omega.
+ assert (R3: forall r, In (R r) srcs -> In r itmps -> False).
+ intros. apply H1 with r. tauto. auto with coqlib.
+ assert (R4: forall r, In (R r) srcs -> In r ftmps -> False).
+ intros. apply H2 with r. tauto. auto with coqlib.
+ assert (R5: list_disjoint itmps ftmps).
+ eapply list_disjoint_cons_left.
+ eapply list_disjoint_cons_right. eauto.
+ assert (R6: list_norepet itmps).
+ inversion H4; auto.
+ assert (R7: list_norepet ftmps).
+ inversion H5; auto.
+ destruct a.
+ (* a is a register *)
+ generalize (IHsrcs itmps ftmps k rs m R1 R2 R3 R4 R5 R6 R7).
+ intros [rs' [EX [RES [OTH1 OTH2]]]].
+ exists rs'. split.
+ unfold add_reload. case (mreg_eq m2 m2); intro; tauto.
+ split. simpl. apply (f_equal2 (@cons val)).
+ apply OTH1.
+ red; intro; apply H1 with m2. tauto. auto with coqlib.
+ red; intro; apply H2 with m2. tauto. auto with coqlib.
+ assumption.
+ split. intros. apply OTH1. simpl in H6; tauto. simpl in H7; tauto.
+ auto.
+ (* a is a stack location *)
+ set (tmp := match slot_type s with Tint => m0 | Tfloat => m1 end).
+ assert (NI: ~(In tmp itmps)).
+ unfold tmp; case (slot_type s).
+ inversion H4; auto.
+ apply list_disjoint_notin with (m1 :: ftmps).
+ apply list_disjoint_sym. apply list_disjoint_cons_left with m0.
+ auto. auto with coqlib.
+ assert (NF: ~(In tmp ftmps)).
+ unfold tmp; case (slot_type s).
+ apply list_disjoint_notin with (m0 :: itmps).
+ apply list_disjoint_cons_right with m1.
+ auto. auto with coqlib.
+ inversion H5; auto.
+ generalize
+ (add_reload_correct (S s) tmp
+ (add_reloads srcs (regs_for_rec srcs itmps ftmps) k) rs m).
+ intros [rs1 [EX1 [RES1 OTH]]].
+ generalize (IHsrcs itmps ftmps k rs1 m R1 R2 R3 R4 R5 R6 R7).
+ intros [rs' [EX [RES [OTH1 OTH2]]]].
+ exists rs'.
+ split. eapply star_trans; eauto. traceEq.
+ split. simpl. apply (f_equal2 (@cons val)).
+ rewrite OTH1; auto.
+ rewrite RES. apply list_map_exten. intros.
+ symmetry. apply OTH.
+ destruct x; try exact I. simpl. red; intro; subst m2.
+ generalize H6; unfold tmp. case (slot_type s).
+ intro. apply H1 with m0. tauto. auto with coqlib.
+ intro. apply H2 with m1. tauto. auto with coqlib.
+ split. intros. simpl in H6; simpl in H7.
+ rewrite OTH1. apply OTH.
+ simpl. unfold tmp. case (slot_type s); tauto.
+ tauto. tauto.
+ intros. rewrite OTH2. apply OTH. exact I.
+Qed.
+
+Lemma add_reloads_correct:
+ forall srcs k rs m,
+ (List.length srcs <= 3)%nat ->
+ Loc.disjoint srcs temporaries ->
+ exists rs',
+ star step ge (State stk f sp (add_reloads srcs (regs_for srcs) k) rs m)
+ E0 (State stk f sp k rs' m) /\
+ reglist rs' (regs_for srcs) = List.map rs srcs /\
+ forall l, Loc.notin l temporaries -> rs' l = rs l.
+Proof.
+ intros.
+ pose (itmps := IT1 :: IT2 :: IT3 :: nil).
+ pose (ftmps := FT1 :: FT2 :: FT3 :: nil).
+ assert (R1: (List.length srcs <= List.length itmps)%nat).
+ unfold itmps; simpl; assumption.
+ assert (R2: (List.length srcs <= List.length ftmps)%nat).
+ unfold ftmps; simpl; assumption.
+ assert (R3: forall r, In (R r) srcs -> In r itmps -> False).
+ intros. assert (In (R r) temporaries).
+ simpl in H2; simpl; intuition congruence.
+ generalize (H0 _ _ H1 H3). simpl. tauto.
+ assert (R4: forall r, In (R r) srcs -> In r ftmps -> False).
+ intros. assert (In (R r) temporaries).
+ simpl in H2; simpl; intuition congruence.
+ generalize (H0 _ _ H1 H3). simpl. tauto.
+ assert (R5: list_disjoint itmps ftmps).
+ red; intros r1 r2; simpl; intuition congruence.
+ assert (R6: list_norepet itmps).
+ unfold itmps. NoRepet.
+ assert (R7: list_norepet ftmps).
+ unfold ftmps. NoRepet.
+ generalize (add_reloads_correct_rec srcs itmps ftmps k rs m
+ R1 R2 R3 R4 R5 R6 R7).
+ intros [rs' [EX [RES [OTH1 OTH2]]]].
+ exists rs'. split. exact EX.
+ split. exact RES.
+ intros. destruct l. apply OTH1.
+ generalize (Loc.notin_not_in _ _ H1). simpl. intuition congruence.
+ generalize (Loc.notin_not_in _ _ H1). simpl. intuition congruence.
+ apply OTH2.
+Qed.
+
+Lemma add_move_correct:
+ forall src dst k rs m,
+ exists rs',
+ star step ge (State stk f sp (add_move src dst k) rs m)
+ E0 (State stk f sp k rs' m) /\
+ rs' dst = rs src /\
+ forall l, Loc.diff l dst -> Loc.diff l (R IT1) -> Loc.diff l (R FT1) -> rs' l = rs l.
+Proof.
+ intros; unfold add_move.
+ case (Loc.eq src dst); intro.
+ subst dst. exists rs. split. apply star_refl. tauto.
+ destruct src.
+ (* src is a register *)
+ generalize (add_spill_correct m0 dst k rs m); intros [rs' [EX [RES OTH]]].
+ exists rs'; intuition. apply OTH; apply Loc.diff_sym; auto.
+ destruct dst.
+ (* src is a stack slot, dst a register *)
+ generalize (add_reload_correct (S s) m0 k rs m); intros [rs' [EX [RES OTH]]].
+ exists rs'; intuition. apply OTH; apply Loc.diff_sym; auto.
+ (* src and dst are stack slots *)
+ set (tmp := match slot_type s with Tint => IT1 | Tfloat => FT1 end).
+ generalize (add_reload_correct (S s) tmp (add_spill tmp (S s0) k) rs m);
+ intros [rs1 [EX1 [RES1 OTH1]]].
+ generalize (add_spill_correct tmp (S s0) k rs1 m);
+ intros [rs2 [EX2 [RES2 OTH2]]].
+ exists rs2. split.
+ eapply star_trans; eauto. traceEq.
+ split. congruence.
+ intros. rewrite OTH2. apply OTH1.
+ apply Loc.diff_sym. unfold tmp; case (slot_type s); auto.
+ apply Loc.diff_sym; auto.
+Qed.
+
+Lemma effect_move_sequence:
+ forall k moves rs m,
+ let k' := List.fold_right (fun p k => add_move (fst p) (snd p) k) k moves in
+ exists rs',
+ star step ge (State stk f sp k' rs m)
+ E0 (State stk f sp k rs' m) /\
+ effect_seqmove moves rs rs'.
+Proof.
+ induction moves; intros until m; simpl.
+ exists rs; split. constructor. constructor.
+ destruct a as [src dst]; simpl.
+ set (k1 := fold_right
+ (fun (p : loc * loc) (k : code) => add_move (fst p) (snd p) k)
+ k moves) in *.
+ destruct (add_move_correct src dst k1 rs m) as [rs1 [A [B C]]].
+ destruct (IHmoves rs1 m) as [rs' [D E]].
+ exists rs'; split.
+ eapply star_trans; eauto. traceEq.
+ econstructor; eauto. red. tauto.
+Qed.
+
+Lemma parallel_move_correct:
+ forall srcs dsts k rs m,
+ List.length srcs = List.length dsts ->
+ Loc.no_overlap srcs dsts ->
+ Loc.norepet dsts ->
+ Loc.disjoint srcs temporaries ->
+ Loc.disjoint dsts temporaries ->
+ exists rs',
+ star step ge (State stk f sp (parallel_move srcs dsts k) rs m)
+ E0 (State stk f sp k rs' m) /\
+ List.map rs' dsts = List.map rs srcs /\
+ rs' (R IT3) = rs (R IT3) /\
+ forall l, Loc.notin l dsts -> Loc.notin l temporaries -> rs' l = rs l.
+Proof.
+ intros.
+ generalize (effect_move_sequence k (parmove srcs dsts) rs m).
+ intros [rs' [EXEC EFFECT]].
+ exists rs'. split. exact EXEC.
+ apply effect_parmove; auto.
+Qed.
+
+Lemma parallel_move_arguments_correct:
+ forall args sg k rs m,
+ List.map Loc.type args = sg.(sig_args) ->
+ locs_acceptable args ->
+ exists rs',
+ star step ge (State stk f sp (parallel_move args (loc_arguments sg) k) rs m)
+ E0 (State stk f sp k rs' m) /\
+ List.map rs' (loc_arguments sg) = List.map rs args /\
+ rs' (R IT3) = rs (R IT3) /\
+ forall l, Loc.notin l (loc_arguments sg) -> Loc.notin l temporaries -> rs' l = rs l.
+Proof.
+ intros. apply parallel_move_correct.
+ transitivity (length sg.(sig_args)).
+ rewrite <- H. symmetry; apply list_length_map.
+ symmetry. apply loc_arguments_length.
+ apply no_overlap_arguments; auto.
+ apply loc_arguments_norepet.
+ apply locs_acceptable_disj_temporaries; auto.
+ apply loc_arguments_not_temporaries.
+Qed.
+
+Lemma parallel_move_parameters_correct:
+ forall params sg k rs m,
+ List.map Loc.type params = sg.(sig_args) ->
+ locs_acceptable params ->
+ Loc.norepet params ->
+ exists rs',
+ star step ge (State stk f sp (parallel_move (loc_parameters sg) params k) rs m)
+ E0 (State stk f sp k rs' m) /\
+ List.map rs' params = List.map rs (loc_parameters sg) /\
+ rs' (R IT3) = rs (R IT3) /\
+ forall l, Loc.notin l params -> Loc.notin l temporaries -> rs' l = rs l.
+Proof.
+ intros. apply parallel_move_correct.
+ transitivity (length sg.(sig_args)).
+ apply loc_parameters_length.
+ rewrite <- H. apply list_length_map.
+ apply no_overlap_parameters; auto.
+ auto. apply loc_parameters_not_temporaries.
+ apply locs_acceptable_disj_temporaries; auto.
+Qed.
+
+End LINEAR_CONSTRUCTORS.
+
+(** * Agreement between values of locations *)
+
+(** The predicate [agree] states that two location maps
+ give the same values to all acceptable locations,
+ that is, non-temporary registers and [Local] stack slots. *)
+
+Definition agree (rs1 rs2: locset) : Prop :=
+ forall l, loc_acceptable l -> rs2 l = rs1 l.
+
+Lemma agree_loc:
+ forall rs1 rs2 l,
+ agree rs1 rs2 -> loc_acceptable l -> rs2 l = rs1 l.
+Proof.
+ auto.
+Qed.
+
+Lemma agree_locs:
+ forall rs1 rs2 ll,
+ agree rs1 rs2 -> locs_acceptable ll -> map rs2 ll = map rs1 ll.
+Proof.
+ induction ll; simpl; intros.
+ auto.
+ f_equal. apply H. apply H0; auto with coqlib.
+ apply IHll; auto. red; intros. apply H0; auto with coqlib.
+Qed.
+
+Lemma agree_exten:
+ forall rs ls1 ls2,
+ agree rs ls1 ->
+ (forall l, Loc.notin l temporaries -> ls2 l = ls1 l) ->
+ agree rs ls2.
+Proof.
+ intros; red; intros. rewrite H0. auto.
+ apply temporaries_not_acceptable; auto.
+Qed.
+
+Lemma agree_set:
+ forall rs1 rs2 rs2' l v,
+ loc_acceptable l ->
+ rs2' l = v ->
+ (forall l', Loc.diff l l' -> Loc.notin l' temporaries -> rs2' l' = rs2 l') ->
+ agree rs1 rs2 -> agree (Locmap.set l v rs1) rs2'.
+Proof.
+ intros; red; intros.
+ destruct (Loc.eq l l0).
+ subst l0. rewrite Locmap.gss. auto.
+ assert (Loc.diff l l0). eapply loc_acceptable_noteq_diff; eauto.
+ rewrite Locmap.gso; auto. rewrite H1. auto. auto.
+ apply temporaries_not_acceptable; auto.
+Qed.
+
+Lemma agree_return_regs:
+ forall rs1 ls1 rs2 ls2,
+ agree rs1 ls1 -> agree rs2 ls2 ->
+ agree (LTL.return_regs rs1 rs2) (LTL.return_regs ls1 ls2).
+Proof.
+ intros; red; intros. unfold LTL.return_regs.
+ assert (~In l temporaries).
+ apply Loc.notin_not_in. apply temporaries_not_acceptable; auto.
+ destruct l.
+ destruct (In_dec Loc.eq (R m) temporaries). contradiction.
+ destruct (In_dec Loc.eq (R m) destroyed_at_call); auto.
+ auto.
+Qed.
+
+Lemma agree_set_result:
+ forall rs1 ls1 rs2 ls2 sig res ls3,
+ loc_acceptable res -> agree rs1 ls1 -> agree rs2 ls2 ->
+ ls3 res = LTL.return_regs ls1 ls2 (R (loc_result sig)) ->
+ (forall l : loc, Loc.diff res l -> ls3 l = LTL.return_regs ls1 ls2 l) ->
+ let rs_merge := LTL.return_regs rs1 rs2 in
+ agree (Locmap.set res (rs_merge (R (loc_result sig))) rs_merge) ls3.
+Proof.
+ intros. apply agree_set with (LTL.return_regs ls1 ls2); auto.
+ rewrite H2; unfold rs_merge.
+ repeat rewrite return_regs_result. apply H1. apply loc_result_acceptable.
+ unfold rs_merge. apply agree_return_regs; auto.
+Qed.
+
+(** [agree_arguments] and [agree_parameters] are two stronger
+ variants of the predicate [agree]. They additionally demand
+ equality of the values of locations that are arguments or parameters
+ (respectively) for a call to a function of signature [sg]. *)
+
+Definition agree_arguments (sg: signature) (rs1 rs2: locset) : Prop :=
+ forall l, loc_acceptable l \/ In l (loc_arguments sg) -> rs2 l = rs1 l.
+
+Definition agree_parameters (sg: signature) (rs1 rs2: locset) : Prop :=
+ forall l, loc_acceptable l \/ In l (loc_parameters sg) -> rs2 l = rs1 l.
+
+Remark parallel_assignment:
+ forall (P: loc -> Prop) (rs1 rs2 ls1 ls2: locset) srcs dsts,
+ map rs2 dsts = map rs1 srcs ->
+ map ls2 dsts = map ls1 srcs ->
+ (forall l, In l srcs -> P l) ->
+ (forall l, P l -> ls1 l = rs1 l) ->
+ (forall l, In l dsts -> ls2 l = rs2 l).
+Proof.
+ induction srcs; destruct dsts; simpl; intros; try congruence.
+ contradiction.
+ inv H; inv H0. elim H3; intro. subst l0.
+ rewrite H5; rewrite H4. auto with coqlib.
+ eapply IHsrcs; eauto.
+Qed.
+
+Lemma agree_set_arguments:
+ forall rs1 ls1 ls2 args sg,
+ agree rs1 ls1 ->
+ List.map Loc.type args = sg.(sig_args) ->
+ locs_acceptable args ->
+ List.map ls2 (loc_arguments sg) = map ls1 args ->
+ (forall l : loc,
+ Loc.notin l (loc_arguments sg) ->
+ Loc.notin l temporaries -> ls2 l = ls1 l) ->
+ agree_arguments sg (LTL.parmov args (loc_arguments sg) rs1) ls2.
+Proof.
+ intros.
+ assert (Loc.norepet (loc_arguments sg)).
+ apply loc_arguments_norepet.
+ assert (List.length args = List.length (loc_arguments sg)).
+ rewrite loc_arguments_length. rewrite <- H0.
+ symmetry. apply list_length_map.
+ destruct (parmov_spec rs1 _ _ H4 H5) as [A B].
+ set (rs2 := LTL.parmov args (loc_arguments sg) rs1) in *.
+ assert (forall l, In l (loc_arguments sg) -> ls2 l = rs2 l).
+ intros.
+ eapply parallel_assignment with (P := loc_acceptable); eauto.
+ red; intros.
+ destruct (In_dec Loc.eq l (loc_arguments sg)).
+ auto.
+ assert (loc_acceptable l) by tauto.
+ assert (Loc.notin l (loc_arguments sg)).
+ eapply loc_acceptable_notin_notin; eauto.
+ rewrite H3; auto. rewrite B; auto.
+ apply temporaries_not_acceptable; auto.
+Qed.
+
+Lemma agree_arguments_agree:
+ forall sg rs ls, agree_arguments sg rs ls -> agree rs ls.
+Proof.
+ intros; red; intros; auto.
+Qed.
+
+Lemma agree_arguments_locs:
+ forall sg rs1 rs2,
+ agree_arguments sg rs1 rs2 ->
+ map rs2 (loc_arguments sg) = map rs1 (loc_arguments sg).
+Proof.
+ intros.
+ assert (forall ll, incl ll (loc_arguments sg) -> map rs2 ll = map rs1 ll).
+ induction ll; simpl; intros. auto.
+ f_equal. apply H. right. apply H0. auto with coqlib.
+ apply IHll. eapply incl_cons_inv; eauto.
+ apply H0. apply incl_refl.
+Qed.
+
+Lemma agree_set_parameters:
+ forall rs1 ls1 ls2 sg params,
+ agree_parameters sg rs1 ls1 ->
+ List.map Loc.type params = sg.(sig_args) ->
+ locs_acceptable params ->
+ Loc.norepet params ->
+ List.map ls2 params = List.map ls1 (loc_parameters sg) ->
+ (forall l : loc,
+ Loc.notin l params ->
+ Loc.notin l temporaries -> ls2 l = ls1 l) ->
+ agree (LTL.parmov (loc_parameters sg) params rs1) ls2.
+Proof.
+ intros.
+ assert (List.length (loc_parameters sg) = List.length params).
+ unfold loc_parameters. rewrite list_length_map.
+ rewrite loc_arguments_length. rewrite <- H0.
+ apply list_length_map.
+ destruct (parmov_spec rs1 _ _ H2 H5) as [A B].
+ set (rs2 := LTL.parmov (loc_parameters sg) params rs1) in *.
+ red; intros.
+ assert (forall l, In l params -> ls2 l = rs2 l).
+ intros.
+ eapply parallel_assignment with (P := fun l => In l (loc_parameters sg)); eauto.
+ destruct (In_dec Loc.eq l params).
+ auto.
+ assert (Loc.notin l params).
+ eapply loc_acceptable_notin_notin; eauto.
+ rewrite B; auto. rewrite H4; auto.
+ apply temporaries_not_acceptable; auto.
+Qed.
+
+Lemma agree_call_regs:
+ forall sg rs ls,
+ agree_arguments sg rs ls ->
+ agree_parameters sg (LTL.call_regs rs) (LTL.call_regs ls).
+Proof.
+ intros; red; intros. elim H0.
+ destruct l; simpl; auto. destruct s; auto.
+ unfold loc_parameters. intro.
+ destruct (list_in_map_inv _ _ _ H1) as [r [A B]].
+ subst l. generalize (loc_arguments_acceptable _ _ B).
+ destruct r; simpl; auto. destruct s; simpl; auto.
+Qed.
+
+Lemma agree_arguments_return_regs:
+ forall sg rs1 rs2 ls1 ls2,
+ tailcall_possible sg ->
+ agree rs1 ls1 ->
+ agree_arguments sg rs2 ls2 ->
+ agree_arguments sg (LTL.return_regs rs1 rs2) (LTL.return_regs ls1 ls2).
+Proof.
+ intros; red; intros. generalize (H1 l H2). intro.
+ elim H2; intro. generalize (H0 l H4); intro.
+ unfold LTL.return_regs. destruct l; auto.
+ destruct (In_dec Loc.eq (R m) temporaries); auto.
+ destruct (In_dec Loc.eq (R m) destroyed_at_call); auto.
+ generalize (H l H4). unfold LTL.return_regs; destruct l; intro.
+ destruct (In_dec Loc.eq (R m) temporaries); auto.
+ destruct (In_dec Loc.eq (R m) destroyed_at_call); auto.
+ contradiction.
+Qed.
+
+(** * Preservation of labels and gotos *)
+
+Lemma find_label_add_spill:
+ forall lbl src dst k,
+ find_label lbl (add_spill src dst k) = find_label lbl k.
+Proof.
+ intros. destruct dst; simpl; auto.
+ destruct (mreg_eq src m); auto.
+Qed.
+
+Lemma find_label_add_reload:
+ forall lbl src dst k,
+ find_label lbl (add_reload src dst k) = find_label lbl k.
+Proof.
+ intros. destruct src; simpl; auto.
+ destruct (mreg_eq m dst); auto.
+Qed.
+
+Lemma find_label_add_reloads:
+ forall lbl srcs dsts k,
+ find_label lbl (add_reloads srcs dsts k) = find_label lbl k.
+Proof.
+ induction srcs; intros; simpl. auto.
+ destruct dsts; auto. rewrite find_label_add_reload. auto.
+Qed.
+
+Lemma find_label_add_move:
+ forall lbl src dst k,
+ find_label lbl (add_move src dst k) = find_label lbl k.
+Proof.
+ intros; unfold add_move.
+ destruct (Loc.eq src dst); auto.
+ destruct src. apply find_label_add_spill.
+ destruct dst. apply find_label_add_reload.
+ rewrite find_label_add_reload. apply find_label_add_spill.
+Qed.
+
+Lemma find_label_parallel_move:
+ forall lbl srcs dsts k,
+ find_label lbl (parallel_move srcs dsts k) = find_label lbl k.
+Proof.
+ intros. unfold parallel_move. generalize (parmove srcs dsts).
+ induction m; simpl. auto.
+ rewrite find_label_add_move. auto.
+Qed.
+
+Hint Rewrite find_label_add_spill find_label_add_reload
+ find_label_add_reloads find_label_add_move
+ find_label_parallel_move: labels.
+
+Opaque reg_for.
+
+Ltac FL := simpl; autorewrite with labels; auto.
+
+Lemma find_label_transf_instr:
+ forall lbl sg instr k,
+ find_label lbl (transf_instr sg instr k) =
+ if LTLin.is_label lbl instr then Some k else find_label lbl k.
+Proof.
+ intros. destruct instr; FL.
+ destruct (is_move_operation o l); FL; FL.
+ FL.
+ destruct s0; FL; FL; FL.
+ destruct s0; FL; FL; FL.
+ FL.
+ destruct o; FL.
+Qed.
+
+Lemma find_label_transf_code:
+ forall sg lbl c,
+ find_label lbl (transf_code sg c) =
+ option_map (transf_code sg) (LTLin.find_label lbl c).
+Proof.
+ induction c; simpl.
+ auto.
+ rewrite find_label_transf_instr.
+ destruct (LTLin.is_label lbl a); auto.
+Qed.
+
+Lemma find_label_transf_function:
+ forall lbl f c,
+ LTLin.find_label lbl (LTLin.fn_code f) = Some c ->
+ find_label lbl (Linear.fn_code (transf_function f)) =
+ Some (transf_code f c).
+Proof.
+ intros. destruct f; simpl in *. FL.
+ rewrite find_label_transf_code. rewrite H; auto.
+Qed.
+
+(** * Semantic preservation *)
+
+Section PRESERVATION.
+
+Variable prog: LTLin.program.
+Let tprog := transf_program prog.
+Hypothesis WT_PROG: LTLintyping.wt_program prog.
+
+Let ge := Genv.globalenv prog.
+Let tge := Genv.globalenv tprog.
+
+Lemma functions_translated:
+ forall v f,
+ Genv.find_funct ge v = Some f ->
+ Genv.find_funct tge v = Some (transf_fundef f).
+Proof (@Genv.find_funct_transf _ _ _ transf_fundef prog).
+
+Lemma function_ptr_translated:
+ forall v f,
+ Genv.find_funct_ptr ge v = Some f ->
+ Genv.find_funct_ptr tge v = Some (transf_fundef f).
+Proof (@Genv.find_funct_ptr_transf _ _ _ transf_fundef prog).
+
+Lemma symbols_preserved:
+ forall id,
+ Genv.find_symbol tge id = Genv.find_symbol ge id.
+Proof (@Genv.find_symbol_transf _ _ _ transf_fundef prog).
+
+Lemma sig_preserved:
+ forall f, funsig (transf_fundef f) = LTLin.funsig f.
+Proof.
+ destruct f; reflexivity.
+Qed.
+
+Lemma find_function_wt:
+ forall ros rs f,
+ LTLin.find_function ge ros rs = Some f -> wt_fundef f.
+Proof.
+ intros until f. destruct ros; simpl.
+ intro. eapply Genv.find_funct_prop with (p := prog); eauto.
+ caseEq (Genv.find_symbol ge i); intros.
+ eapply Genv.find_funct_ptr_prop with (p := prog); eauto.
+ congruence.
+Qed.
+
+(** The [match_state] predicate relates states in the original LTLin
+ program and the transformed Linear program. The main property
+ it enforces are:
+- Agreement between the values of locations in the two programs,
+ according to the [agree] or [agree_arguments] predicates.
+- Lists of LTLin instructions appearing in the source state
+ are always suffixes of the code for the corresponding functions.
+- Well-typedness of the source code, which ensures that
+ only acceptable locations are accessed by this code.
+*)
+
+Inductive match_stackframes: list LTLin.stackframe -> list Linear.stackframe -> signature -> Prop :=
+ | match_stackframes_nil:
+ forall tyargs,
+ match_stackframes nil nil (mksignature tyargs (Some Tint))
+ | match_stackframes_cons:
+ forall res f sp c rs s s' c' ls sig,
+ match_stackframes s s' (LTLin.fn_sig f) ->
+ c' = add_spill (loc_result sig) res (transf_code f c) ->
+ agree rs ls ->
+ loc_acceptable res ->
+ wt_function f ->
+ is_tail c (LTLin.fn_code f) ->
+ match_stackframes (LTLin.Stackframe res f sp rs c :: s)
+ (Linear.Stackframe (transf_function f) sp ls c' :: s')
+ sig.
+
+Inductive match_states: LTLin.state -> Linear.state -> Prop :=
+ | match_states_intro:
+ forall s f sp c rs m s' ls
+ (STACKS: match_stackframes s s' (LTLin.fn_sig f))
+ (AG: agree rs ls)
+ (WT: wt_function f)
+ (TL: is_tail c (LTLin.fn_code f)),
+ match_states (LTLin.State s f sp c rs m)
+ (Linear.State s' (transf_function f) sp (transf_code f c) ls m)
+ | match_states_call:
+ forall s f rs m s' ls
+ (STACKS: match_stackframes s s' (LTLin.funsig f))
+ (AG: agree_arguments (LTLin.funsig f) rs ls)
+ (WT: wt_fundef f),
+ match_states (LTLin.Callstate s f rs m)
+ (Linear.Callstate s' (transf_fundef f) ls m)
+ | match_states_return:
+ forall s sig rs m s' ls
+ (STACKS: match_stackframes s s' sig)
+ (AG: agree rs ls),
+ match_states (LTLin.Returnstate s sig rs m)
+ (Linear.Returnstate s' ls m).
+
+Remark parent_locset_match:
+ forall s s' sig,
+ match_stackframes s s' sig ->
+ agree (LTLin.parent_locset s) (parent_locset s').
+Proof.
+ induction 1; simpl.
+ red; intros; auto.
+ auto.
+Qed.
+
+Remark match_stackframes_inv:
+ forall s ts sig,
+ match_stackframes s ts sig ->
+ forall sig', sig_res sig' = sig_res sig ->
+ match_stackframes s ts sig'.
+Proof.
+ induction 1; intros.
+ destruct sig'. simpl in H; inv H. constructor.
+ assert (loc_result sig' = loc_result sig).
+ unfold loc_result. rewrite H5; auto.
+ econstructor; eauto. rewrite H6; auto.
+Qed.
+
+Ltac ExploitWT :=
+ match goal with
+ | [ WT: wt_function _, TL: is_tail _ _ |- _ ] =>
+ generalize (wt_instrs _ WT _ (is_tail_in TL)); intro WTI
+ end.
+
+(** The proof of semantic preservation is a simulation argument
+ based on diagrams of the following form:
+<<
+ st1 --------------- st2
+ | |
+ t| *|t
+ | |
+ v v
+ st1'--------------- st2'
+>>
+ It is possible for the transformed code to take no transition,
+ remaining in the same state; for instance, if the source transition
+ corresponds to a move instruction that was eliminated.
+ To ensure that this cannot occur infinitely often in a row,
+ we use the following [measure] function that just counts the
+ remaining number of instructions in the source code sequence. *)
+
+Definition measure (st: LTLin.state) : nat :=
+ match st with
+ | LTLin.State s f sp c ls m => List.length c
+ | LTLin.Callstate s f ls m => 0%nat
+ | LTLin.Returnstate s sig ls m => 0%nat
+ end.
+
+Theorem transf_step_correct:
+ forall s1 t s2, LTLin.step ge s1 t s2 ->
+ forall s1' (MS: match_states s1 s1'),
+ (exists s2', plus Linear.step tge s1' t s2' /\ match_states s2 s2')
+ \/ (measure s2 < measure s1 /\ t = E0 /\ match_states s2 s1')%nat.
+Proof.
+ Opaque regs_for. Opaque add_reloads.
+ induction 1; intros; try inv MS; simpl.
+
+ (* Lop *)
+ ExploitWT. inv WTI.
+ (* move *)
+ simpl.
+ destruct (add_move_correct tge s' (transf_function f) sp r1 res (transf_code f b) ls m)
+ as [ls2 [A [B C]]].
+ inv A.
+ right. split. omega. split. auto.
+ rewrite H1. rewrite H1. econstructor; eauto with coqlib.
+ apply agree_set with ls2; auto.
+ rewrite B. simpl in H; inversion H. auto.
+ left; econstructor; split. eapply plus_left; eauto.
+ econstructor; eauto with coqlib.
+ apply agree_set with ls; auto.
+ rewrite B. simpl in H; inversion H. auto.
+ intros. simpl in H1. apply C. apply Loc.diff_sym; auto.
+ simpl in H7; tauto. simpl in H7; tauto.
+ (* other ops *)
+ assert (is_move_operation op args = None).
+ caseEq (is_move_operation op args); intros.
+ destruct (is_move_operation_correct _ _ H0). congruence.
+ auto.
+ rewrite H0.
+ exploit add_reloads_correct.
+ eapply length_op_args; eauto.
+ apply locs_acceptable_disj_temporaries; auto.
+ intros [ls2 [A [B C]]].
+ exploit add_spill_correct.
+ intros [ls3 [D [E F]]].
+ left; econstructor; split.
+ eapply star_plus_trans. eexact A.
+ eapply plus_left. eapply exec_Lop with (v := v).
+ rewrite <- H. rewrite B. rewrite (agree_locs _ _ _ AG H5).
+ apply eval_operation_preserved. exact symbols_preserved.
+ eexact D. eauto. traceEq.
+ econstructor; eauto with coqlib.
+ apply agree_set with ls; auto.
+ rewrite E. apply Locmap.gss.
+ intros. rewrite F; auto. rewrite Locmap.gso. auto.
+ apply reg_for_diff; auto.
+
+ (* Lload *)
+ ExploitWT; inv WTI.
+ exploit add_reloads_correct.
+ apply le_S. eapply length_addr_args; eauto.
+ apply locs_acceptable_disj_temporaries; auto.
+ intros [ls2 [A [B C]]].
+ exploit add_spill_correct.
+ intros [ls3 [D [E F]]].
+ left; econstructor; split.
+ eapply star_plus_trans. eauto.
+ eapply plus_left. eapply exec_Lload; eauto.
+ rewrite B. rewrite <- H. rewrite (agree_locs _ _ _ AG H7).
+ apply eval_addressing_preserved. exact symbols_preserved.
+ eauto. auto. traceEq.
+ econstructor; eauto with coqlib.
+ apply agree_set with ls; auto.
+ rewrite E. apply Locmap.gss.
+ intros. rewrite F; auto. rewrite Locmap.gso. auto.
+ apply reg_for_diff; auto.
+
+ (* Lstore *)
+ ExploitWT; inv WTI.
+ assert (exists rsrc, exists rargs, regs_for (src :: args) = rsrc :: rargs).
+ Transparent regs_for. unfold regs_for. simpl.
+ destruct src. econstructor; econstructor; eauto.
+ destruct (slot_type s0); econstructor; econstructor; eauto.
+ destruct H1 as [rsrc [rargs EQ]]. rewrite EQ.
+ assert (length (src :: args) <= 3)%nat.
+ simpl. apply le_n_S.
+ eapply length_addr_args; eauto.
+ exploit add_reloads_correct.
+ eauto. apply locs_acceptable_disj_temporaries; auto.
+ red; intros. elim H2; intro; auto. subst l; auto.
+ intros [ls2 [A [B C]]]. rewrite EQ in A. rewrite EQ in B.
+ injection B. intros D E.
+ simpl in B.
+ left; econstructor; split.
+ eapply plus_right. eauto.
+ eapply exec_Lstore with (a := a); eauto.
+ rewrite D. rewrite <- H. rewrite (agree_locs _ _ _ AG H7).
+ apply eval_addressing_preserved. exact symbols_preserved.
+ rewrite E. rewrite (agree_loc _ _ _ AG H8). eauto.
+ traceEq.
+ econstructor; eauto with coqlib.
+ apply agree_exten with ls; auto.
+
+ (* Lcall *)
+ inversion MS. subst s0 f0 sp0 c rs0 m0.
+ simpl transf_code.
+ ExploitWT. inversion WTI. subst sig0 ros0 args0 res0.
+ assert (WTF': wt_fundef f'). eapply find_function_wt; eauto.
+ destruct ros as [fn | id].
+ (* indirect call *)
+ destruct (add_reload_correct tge s' (transf_function f) sp fn IT3
+ (parallel_move args (loc_arguments sig)
+ (Lcall sig (inl ident IT3)
+ :: add_spill (loc_result sig) res (transf_code f b)))
+ ls m)
+ as [ls2 [A [B C]]].
+ destruct (parallel_move_arguments_correct tge s' (transf_function f) sp
+ args sig
+ (Lcall sig (inl ident IT3)
+ :: add_spill (loc_result sig) res (transf_code f b))
+ ls2 m H7 H10)
+ as [ls3 [D [E [F G]]]].
+ assert (AG_ARGS: agree_arguments (LTLin.funsig f') rs1 ls3).
+ rewrite <- H0.
+ unfold rs1. apply agree_set_arguments with ls; auto.
+ rewrite E. apply list_map_exten; intros. symmetry. apply C.
+ assert (Loc.notin x temporaries). apply temporaries_not_acceptable; auto.
+ simpl in H3. apply Loc.diff_sym. tauto.
+ intros. rewrite G; auto. apply C.
+ simpl in H3. apply Loc.diff_sym. tauto.
+ left; econstructor; split.
+ eapply star_plus_trans. eauto. eapply plus_right. eauto.
+ eapply exec_Lcall; eauto.
+ simpl. rewrite F. rewrite B.
+ rewrite (agree_loc rs ls fn); auto.
+ apply functions_translated. eauto.
+ rewrite H0; symmetry; apply sig_preserved.
+ eauto. traceEq.
+ econstructor; eauto.
+ econstructor; eauto with coqlib.
+ rewrite H0. auto.
+ eapply agree_arguments_agree; eauto.
+ (* direct call *)
+ destruct (parallel_move_arguments_correct tge s' (transf_function f) sp
+ args sig
+ (Lcall sig (inr mreg id)
+ :: add_spill (loc_result sig) res (transf_code f b))
+ ls m H7 H10)
+ as [ls3 [D [E [F G]]]].
+ assert (AG_ARGS: agree_arguments (LTLin.funsig f') rs1 ls3).
+ rewrite <- H0.
+ unfold rs1. apply agree_set_arguments with ls; auto.
+ left; econstructor; split.
+ eapply plus_right. eauto.
+ eapply exec_Lcall; eauto.
+ simpl. rewrite symbols_preserved.
+ generalize H; simpl. destruct (Genv.find_symbol ge id).
+ apply function_ptr_translated; auto. congruence.
+ rewrite H0. symmetry; apply sig_preserved.
+ traceEq.
+ econstructor; eauto.
+ econstructor; eauto with coqlib.
+ rewrite H0; auto.
+ eapply agree_arguments_agree; eauto.
+
+ (* Ltailcall *)
+ inversion MS. subst s0 f0 sp c rs0 m0 s1'.
+ simpl transf_code.
+ ExploitWT. inversion WTI. subst sig0 ros0 args0.
+ assert (WTF': wt_fundef f'). eapply find_function_wt; eauto.
+ destruct ros as [fn | id].
+ (* indirect call *)
+ destruct (add_reload_correct tge s' (transf_function f) (Vptr stk Int.zero) fn IT3
+ (parallel_move args (loc_arguments sig)
+ (Ltailcall sig (inl ident IT3) :: transf_code f b))
+ ls m)
+ as [ls2 [A [B C]]].
+ destruct (parallel_move_arguments_correct tge s' (transf_function f) (Vptr stk Int.zero)
+ args sig
+ (Ltailcall sig (inl ident IT3) :: transf_code f b)
+ ls2 m H5 H7)
+ as [ls3 [D [E [F G]]]].
+ assert (AG_ARGS: agree_arguments (LTLin.funsig f') rs2 (LTL.return_regs (parent_locset s') ls3)).
+ rewrite <- H0. unfold rs2.
+ apply agree_arguments_return_regs; auto.
+ eapply parent_locset_match; eauto.
+ unfold rs1. apply agree_set_arguments with ls; auto.
+ rewrite E. apply list_map_exten; intros. symmetry. apply C.
+ assert (Loc.notin x temporaries). apply temporaries_not_acceptable; auto.
+ simpl in H2. apply Loc.diff_sym. tauto.
+ intros. rewrite G; auto. apply C.
+ simpl in H2. apply Loc.diff_sym. tauto.
+ left; econstructor; split.
+ eapply star_plus_trans. eauto. eapply plus_right. eauto.
+ eapply exec_Ltailcall; eauto.
+ simpl. rewrite F. rewrite B.
+ rewrite (agree_loc rs ls fn); auto.
+ apply functions_translated. eauto.
+ rewrite H0; symmetry; apply sig_preserved.
+ eauto. traceEq.
+ econstructor; eauto.
+ eapply match_stackframes_inv; eauto. congruence.
+
+ (* direct call *)
+ destruct (parallel_move_arguments_correct tge s' (transf_function f) (Vptr stk Int.zero)
+ args sig
+ (Ltailcall sig (inr mreg id) :: transf_code f b)
+ ls m H5 H7)
+ as [ls3 [D [E [F G]]]].
+ assert (AG_ARGS: agree_arguments (LTLin.funsig f') rs2 (LTL.return_regs (parent_locset s') ls3)).
+ rewrite <- H0. unfold rs2.
+ apply agree_arguments_return_regs; auto.
+ eapply parent_locset_match; eauto.
+ unfold rs1. apply agree_set_arguments with ls; auto.
+ left; econstructor; split.
+ eapply plus_right. eauto.
+ eapply exec_Ltailcall; eauto.
+ simpl. rewrite symbols_preserved.
+ generalize H; simpl. destruct (Genv.find_symbol ge id).
+ apply function_ptr_translated; auto. congruence.
+ rewrite H0. symmetry; apply sig_preserved.
+ traceEq.
+ econstructor; eauto.
+ eapply match_stackframes_inv; eauto. congruence.
+
+ (* Lalloc *)
+ ExploitWT; inv WTI.
+ exploit add_reload_correct. intros [ls2 [A [B C]]].
+ exploit add_spill_correct. intros [ls3 [D [E F]]].
+ left; econstructor; split.
+ eapply star_plus_trans. eauto.
+ eapply plus_left. eapply exec_Lalloc; eauto.
+ rewrite B. rewrite <- H. apply AG. auto.
+ eauto. eauto. traceEq.
+ econstructor; eauto with coqlib.
+ unfold rs3; apply agree_set with (Locmap.set (R loc_alloc_result) (Vptr blk Int.zero) ls2).
+ auto. rewrite E. rewrite Locmap.gss.
+ unfold rs2; rewrite Locmap.gss. auto.
+ auto.
+ unfold rs2. apply agree_set with ls2.
+ unfold loc_alloc_result; simpl; intuition congruence.
+ apply Locmap.gss. intros. apply Locmap.gso; auto.
+ unfold rs1. apply agree_set with ls.
+ unfold loc_alloc_argument; simpl; intuition congruence.
+ rewrite B. apply AG; auto. auto. auto.
+
+ (* Llabel *)
+ left; econstructor; split.
+ apply plus_one. apply exec_Llabel.
+ econstructor; eauto with coqlib.
+
+ (* Lgoto *)
+ left; econstructor; split.
+ apply plus_one. apply exec_Lgoto. apply find_label_transf_function; eauto.
+ econstructor; eauto.
+ eapply LTLin.find_label_is_tail; eauto.
+
+ (* Lcond true *)
+ ExploitWT; inv WTI.
+ exploit add_reloads_correct.
+ eapply length_cond_args; eauto.
+ apply locs_acceptable_disj_temporaries; auto.
+ intros [ls2 [A [B C]]].
+ left; econstructor; split.
+ eapply plus_right. eauto. eapply exec_Lcond_true; eauto.
+ rewrite B. rewrite (agree_locs _ _ _ AG H5). auto.
+ apply find_label_transf_function; eauto.
+ traceEq.
+ econstructor; eauto.
+ apply agree_exten with ls; auto.
+ eapply LTLin.find_label_is_tail; eauto.
+
+ (* Lcond false *)
+ ExploitWT; inv WTI.
+ exploit add_reloads_correct.
+ eapply length_cond_args; eauto.
+ apply locs_acceptable_disj_temporaries; auto.
+ intros [ls2 [A [B C]]].
+ left; econstructor; split.
+ eapply plus_right. eauto. eapply exec_Lcond_false; eauto.
+ rewrite B. rewrite (agree_locs _ _ _ AG H4). auto.
+ traceEq.
+ econstructor; eauto with coqlib.
+ apply agree_exten with ls; auto.
+
+ (* Lreturn *)
+ ExploitWT; inv WTI.
+ unfold rs2, rs1; destruct or; simpl.
+ (* with an argument *)
+ exploit add_reload_correct.
+ intros [ls2 [A [B C]]].
+ left; econstructor; split.
+ eapply plus_right. eauto. eapply exec_Lreturn; eauto.
+ traceEq.
+ econstructor; eauto.
+ apply agree_return_regs; auto.
+ eapply parent_locset_match; eauto.
+ apply agree_set with ls.
+ apply loc_result_acceptable.
+ rewrite B. eapply agree_loc; eauto.
+ auto. auto.
+ (* without an argument *)
+ left; econstructor; split.
+ apply plus_one. eapply exec_Lreturn; eauto.
+ econstructor; eauto.
+ apply agree_return_regs; auto.
+ eapply parent_locset_match; eauto.
+
+ (* internal function *)
+ simpl in WT. inversion_clear WT. inversion H0. simpl in AG.
+ destruct (parallel_move_parameters_correct tge s' (transf_function f)
+ (Vptr stk Int.zero) (LTLin.fn_params f) (LTLin.fn_sig f)
+ (transf_code f (LTLin.fn_code f)) (LTL.call_regs ls) m'
+ wt_params wt_acceptable wt_norepet)
+ as [ls2 [A [B [C D]]]].
+ assert (AG2: agree rs2 ls2).
+ unfold rs2. eapply agree_set_parameters; eauto.
+ unfold rs1. apply agree_call_regs; auto.
+ left; econstructor; split.
+ eapply plus_left.
+ eapply exec_function_internal; eauto.
+ simpl. eauto. traceEq.
+ econstructor; eauto with coqlib.
+
+ (* external function *)
+ left; econstructor; split.
+ apply plus_one. eapply exec_function_external; eauto.
+ unfold args. symmetry. eapply agree_arguments_locs; auto.
+ econstructor; eauto.
+ unfold rs1. apply agree_set with ls; auto.
+ apply loc_result_acceptable.
+ apply Locmap.gss.
+ intros. apply Locmap.gso; auto.
+ eapply agree_arguments_agree; eauto.
+
+ (* return *)
+ inv STACKS.
+ exploit add_spill_correct. intros [ls2 [A [B C]]].
+ left; econstructor; split.
+ eapply plus_left. eapply exec_return; eauto.
+ eauto. traceEq.
+ econstructor; eauto.
+ unfold rs1. apply agree_set with ls; auto.
+ rewrite B. apply AG. apply loc_result_acceptable.
+Qed.
+
+Lemma transf_initial_states:
+ forall st1, LTLin.initial_state prog st1 ->
+ exists st2, Linear.initial_state tprog st2 /\ match_states st1 st2.
+Proof.
+ intros. inversion H.
+ econstructor; split.
+ econstructor.
+ change (prog_main tprog) with (prog_main prog).
+ rewrite symbols_preserved. eauto.
+ apply function_ptr_translated; eauto.
+ rewrite sig_preserved. auto.
+ replace (Genv.init_mem tprog) with (Genv.init_mem prog).
+ econstructor; eauto. rewrite H2. constructor.
+ red; intros. auto.
+ eapply Genv.find_funct_ptr_prop; eauto.
+ symmetry. unfold tprog, transf_program. apply Genv.init_mem_transf; auto.
+Qed.
+
+Lemma transf_final_states:
+ forall st1 st2 r,
+ match_states st1 st2 -> LTLin.final_state st1 r -> Linear.final_state st2 r.
+Proof.
+ intros. inv H0. inv H. inv STACKS. econstructor.
+ rewrite (agree_loc _ _ (R R3) AG). auto.
+ simpl. intuition congruence.
+Qed.
+
+Theorem transf_program_correct:
+ forall (beh: program_behavior),
+ LTLin.exec_program prog beh -> Linear.exec_program tprog beh.
+Proof.
+ unfold LTLin.exec_program, Linear.exec_program; intros.
+ eapply simulation_star_preservation; eauto.
+ eexact transf_initial_states.
+ eexact transf_final_states.
+ eexact transf_step_correct.
+Qed.
+
+End PRESERVATION.
diff --git a/backend/Reloadtyping.v b/backend/Reloadtyping.v
new file mode 100644
index 0000000..155c174
--- /dev/null
+++ b/backend/Reloadtyping.v
@@ -0,0 +1,309 @@
+(** Proof of type preservation for Reload and of
+ correctness of computation of stack bounds for Linear. *)
+
+Require Import Coqlib.
+Require Import Maps.
+Require Import AST.
+Require Import Op.
+Require Import Locations.
+Require Import LTLin.
+Require Import LTLintyping.
+Require Import Linear.
+Require Import Lineartyping.
+Require Import Conventions.
+Require Import Parallelmove.
+Require Import Reload.
+Require Import Reloadproof.
+
+(** * Typing Linear constructors *)
+
+(** We show that the Linear constructor functions defined in [Reload]
+ generate well-typed instruction sequences,
+ given sufficient typing and well-formedness hypotheses over the locations involved. *)
+
+Hint Resolve wt_Lgetstack wt_Lsetstack wt_Lopmove
+ wt_Lop wt_Lload wt_Lstore wt_Lcall wt_Ltailcall wt_Lalloc
+ wt_Llabel wt_Lgoto wt_Lcond wt_Lreturn: reloadty.
+
+Remark wt_code_cons:
+ forall f i c, wt_instr f i -> wt_code f c -> wt_code f (i :: c).
+Proof.
+ intros; red; simpl; intros. elim H1; intro.
+ subst i; auto. auto.
+Qed.
+
+Hint Resolve wt_code_cons: reloadty.
+
+Definition loc_valid (f: function) (l: loc) :=
+ match l with R _ => True | S s => slot_valid f s end.
+
+Lemma loc_acceptable_valid:
+ forall f l, loc_acceptable l -> loc_valid f l.
+Proof.
+ destruct l; simpl; intro. auto.
+ destruct s; simpl. omega. tauto. tauto.
+Qed.
+
+Definition loc_writable (l: loc) :=
+ match l with R _ => True | S s => slot_writable s end.
+
+Lemma loc_acceptable_writable:
+ forall l, loc_acceptable l -> loc_writable l.
+Proof.
+ destruct l; simpl; intro. auto.
+ destruct s; simpl; tauto.
+Qed.
+
+Hint Resolve loc_acceptable_valid loc_acceptable_writable: reloadty.
+
+Definition locs_valid (f: function) (ll: list loc) :=
+ forall l, In l ll -> loc_valid f l.
+Definition locs_writable (ll: list loc) :=
+ forall l, In l ll -> loc_writable l.
+
+Lemma locs_acceptable_valid:
+ forall f ll, locs_acceptable ll -> locs_valid f ll.
+Proof.
+ unfold locs_acceptable, locs_valid. auto with reloadty.
+Qed.
+
+Lemma locs_acceptable_writable:
+ forall ll, locs_acceptable ll -> locs_writable ll.
+Proof.
+ unfold locs_acceptable, locs_writable. auto with reloadty.
+Qed.
+
+Hint Resolve locs_acceptable_valid locs_acceptable_writable: reloadty.
+
+Lemma wt_add_reload:
+ forall f src dst k,
+ loc_valid f src -> Loc.type src = mreg_type dst ->
+ wt_code f k -> wt_code f (add_reload src dst k).
+Proof.
+ intros; unfold add_reload.
+ destruct src; eauto with reloadty.
+ destruct (mreg_eq m dst); eauto with reloadty.
+Qed.
+
+Hint Resolve wt_add_reload: reloadty.
+
+Lemma wt_add_reloads:
+ forall f srcs dsts k,
+ locs_valid f srcs -> map Loc.type srcs = map mreg_type dsts ->
+ wt_code f k -> wt_code f (add_reloads srcs dsts k).
+Proof.
+ induction srcs; destruct dsts; simpl; intros; try congruence.
+ auto. inv H0. apply wt_add_reload; auto with coqlib reloadty.
+ apply IHsrcs; auto. red; intros; auto with coqlib.
+Qed.
+
+Hint Resolve wt_add_reloads: reloadty.
+
+Lemma wt_add_spill:
+ forall f src dst k,
+ loc_valid f dst -> loc_writable dst -> Loc.type dst = mreg_type src ->
+ wt_code f k -> wt_code f (add_spill src dst k).
+Proof.
+ intros; unfold add_spill.
+ destruct dst; eauto with reloadty.
+ destruct (mreg_eq src m); eauto with reloadty.
+Qed.
+
+Hint Resolve wt_add_spill: reloadty.
+
+Lemma wt_add_move:
+ forall f src dst k,
+ loc_valid f src -> loc_valid f dst -> loc_writable dst ->
+ Loc.type dst = Loc.type src ->
+ wt_code f k -> wt_code f (add_move src dst k).
+Proof.
+ intros. unfold add_move.
+ destruct (Loc.eq src dst); auto.
+ destruct src; auto with reloadty.
+ destruct dst; auto with reloadty.
+ set (tmp := match slot_type s with
+ | Tint => IT1
+ | Tfloat => FT1
+ end).
+ assert (mreg_type tmp = Loc.type (S s)).
+ simpl. destruct (slot_type s); reflexivity.
+ apply wt_add_reload; auto with reloadty.
+ apply wt_add_spill; auto. congruence.
+Qed.
+
+Hint Resolve wt_add_move: reloadty.
+
+Lemma wt_add_moves:
+ forall f b moves,
+ (forall s d, In (s, d) moves ->
+ loc_valid f s /\ loc_valid f d /\ loc_writable d /\ Loc.type s = Loc.type d) ->
+ wt_code f b ->
+ wt_code f
+ (List.fold_right (fun p k => add_move (fst p) (snd p) k) b moves).
+Proof.
+ induction moves; simpl; intros.
+ auto.
+ destruct a as [s d]. simpl.
+ destruct (H s d) as [A [B [C D]]]. auto.
+ auto with reloadty.
+Qed.
+
+Theorem wt_parallel_move:
+ forall f srcs dsts b,
+ List.map Loc.type srcs = List.map Loc.type dsts ->
+ locs_valid f srcs -> locs_valid f dsts -> locs_writable dsts ->
+ wt_code f b -> wt_code f (parallel_move srcs dsts b).
+Proof.
+ intros. unfold parallel_move. apply wt_add_moves; auto.
+ intros.
+ elim (parmove_prop_2 _ _ _ _ H4); intros A B.
+ split. destruct A as [C|[C|C]]; auto; subst s; exact I.
+ split. destruct B as [C|[C|C]]; auto; subst d; exact I.
+ split. destruct B as [C|[C|C]]; auto; subst d; exact I.
+ eapply parmove_prop_3; eauto.
+Qed.
+Hint Resolve wt_parallel_move: reloadty.
+
+Lemma wt_reg_for:
+ forall l, mreg_type (reg_for l) = Loc.type l.
+Proof.
+ intros. destruct l; simpl. auto.
+ case (slot_type s); reflexivity.
+Qed.
+Hint Resolve wt_reg_for: reloadty.
+
+Lemma wt_regs_for_rec:
+ forall locs itmps ftmps,
+ (List.length locs <= List.length itmps)%nat ->
+ (List.length locs <= List.length ftmps)%nat ->
+ (forall r, In r itmps -> mreg_type r = Tint) ->
+ (forall r, In r ftmps -> mreg_type r = Tfloat) ->
+ List.map mreg_type (regs_for_rec locs itmps ftmps) = List.map Loc.type locs.
+Proof.
+ induction locs; intros.
+ simpl. auto.
+ destruct itmps; simpl in H. omegaContradiction.
+ destruct ftmps; simpl in H0. omegaContradiction.
+ simpl. apply (f_equal2 (@cons typ)).
+ destruct a. reflexivity. simpl. case (slot_type s).
+ apply H1; apply in_eq. apply H2; apply in_eq.
+ apply IHlocs. omega. omega.
+ intros; apply H1; apply in_cons; auto.
+ intros; apply H2; apply in_cons; auto.
+Qed.
+
+Lemma wt_regs_for:
+ forall locs,
+ (List.length locs <= 3)%nat ->
+ List.map mreg_type (regs_for locs) = List.map Loc.type locs.
+Proof.
+ intros. unfold regs_for. apply wt_regs_for_rec.
+ simpl. auto. simpl. auto.
+ simpl; intros; intuition; subst r; reflexivity.
+ simpl; intros; intuition; subst r; reflexivity.
+Qed.
+Hint Resolve wt_regs_for: reloadty.
+
+Hint Resolve length_op_args length_addr_args length_cond_args: reloadty.
+
+Hint Extern 4 (_ = _) => congruence : reloadty.
+
+Lemma wt_transf_instr:
+ forall f instr k,
+ LTLintyping.wt_instr (LTLin.fn_sig f) instr ->
+ wt_code (transf_function f) k ->
+ wt_code (transf_function f) (transf_instr f instr k).
+Proof.
+ Opaque reg_for regs_for.
+ intros. inv H; simpl; auto with reloadty.
+ caseEq (is_move_operation op args); intros.
+ destruct (is_move_operation_correct _ _ H). congruence.
+ assert (map mreg_type (regs_for args) = map Loc.type args).
+ eauto with reloadty.
+ assert (mreg_type (reg_for res) = Loc.type res). eauto with reloadty.
+ auto with reloadty.
+
+ assert (map mreg_type (regs_for args) = map Loc.type args).
+ eauto with reloadty.
+ assert (mreg_type (reg_for dst) = Loc.type dst). eauto with reloadty.
+ auto with reloadty.
+
+ caseEq (regs_for (src :: args)); intros.
+ red; simpl; tauto.
+ assert (map mreg_type (regs_for (src :: args)) = map Loc.type (src :: args)).
+ apply wt_regs_for. simpl. apply le_n_S. eauto with reloadty.
+ rewrite H in H5. injection H5; intros.
+ auto with reloadty.
+
+ assert (locs_valid (transf_function f) (loc_arguments sig)).
+ red; intros. generalize (loc_arguments_acceptable sig l H).
+ destruct l; simpl; auto. destruct s; simpl; intuition.
+ assert (locs_writable (loc_arguments sig)).
+ red; intros. generalize (loc_arguments_acceptable sig l H7).
+ destruct l; simpl; auto. destruct s; simpl; intuition.
+ assert (map Loc.type args = map Loc.type (loc_arguments sig)).
+ rewrite loc_arguments_type; auto.
+ assert (Loc.type res = mreg_type (loc_result sig)).
+ rewrite H3. unfold loc_result.
+ destruct (sig_res sig); auto. destruct t; auto.
+ destruct ros; auto 10 with reloadty.
+
+ assert (locs_valid (transf_function f) (loc_arguments sig)).
+ red; intros. generalize (loc_arguments_acceptable sig l H).
+ destruct l; simpl; auto. destruct s; simpl; intuition.
+ assert (locs_writable (loc_arguments sig)).
+ red; intros. generalize (loc_arguments_acceptable sig l H7).
+ destruct l; simpl; auto. destruct s; simpl; intuition.
+ assert (map Loc.type args = map Loc.type (loc_arguments sig)).
+ rewrite loc_arguments_type; auto.
+ destruct ros; auto 10 with reloadty.
+
+ assert (map mreg_type (regs_for args) = map Loc.type args).
+ eauto with reloadty.
+ auto with reloadty.
+
+ destruct optres; simpl in *; auto with reloadty.
+ apply wt_add_reload; auto with reloadty.
+ unfold loc_result. rewrite <- H1.
+ destruct (Loc.type l); reflexivity.
+Qed.
+
+Lemma wt_transf_code:
+ forall f c,
+ LTLintyping.wt_code (LTLin.fn_sig f) c ->
+ Lineartyping.wt_code (transf_function f) (transf_code f c).
+Proof.
+ induction c; simpl; intros.
+ red; simpl; tauto.
+ apply wt_transf_instr; auto with coqlib.
+ apply IHc. red; auto with coqlib.
+Qed.
+
+Lemma wt_transf_fundef:
+ forall fd,
+ LTLintyping.wt_fundef fd ->
+ Lineartyping.wt_fundef (transf_fundef fd).
+Proof.
+ intros. destruct fd; simpl.
+ inv H. inv H1. constructor. unfold wt_function. simpl.
+ apply wt_parallel_move; auto with reloadty.
+ rewrite loc_parameters_type. auto.
+ unfold loc_parameters; red; intros.
+ destruct (list_in_map_inv _ _ _ H) as [r [A B]]. rewrite A.
+ generalize (loc_arguments_acceptable _ _ B).
+ destruct r; simpl; auto. destruct s; try tauto.
+ intros; simpl. split. omega.
+ apply loc_arguments_bounded; auto.
+ apply wt_transf_code; auto.
+ constructor.
+Qed.
+
+Lemma program_typing_preserved:
+ forall p,
+ LTLintyping.wt_program p ->
+ Lineartyping.wt_program (transf_program p).
+Proof.
+ intros; red; intros.
+ destruct (transform_program_function _ _ _ _ H0) as [f0 [A B]].
+ subst f; apply wt_transf_fundef. eauto.
+Qed.
diff --git a/backend/Cmconstr.v b/backend/Selection.v
index 2cc947c..c98e55e 100644
--- a/backend/Cmconstr.v
+++ b/backend/Selection.v
@@ -1,47 +1,37 @@
-(** Smart constructors for Cminor. This library provides functions
- for building Cminor expressions and statements, especially expressions
- consisting of operator applications. These functions examine their
- arguments to choose cheaper forms of operators whenever possible.
+(** Instruction selection *)
- For instance, [add e1 e2] will return a Cminor expression semantically
- equivalent to [Eop Oadd (e1 ::: e2 ::: Enil)], but will use a
- [Oaddimm] operator if one of the arguments is an integer constant,
- or suppress the addition altogether if one of the arguments is the
- null integer. In passing, we perform operator reassociation
- ([(e + c1) * c2] becomes [(e * c2) + (c1 * c2)]) and a small amount
- of constant propagation.
+(** The instruction selection pass recognizes opportunities for using
+ combined arithmetic and logical operations and addressing modes
+ offered by the target processor. For instance, the expression [x + 1]
+ can take advantage of the "immediate add" instruction of the processor,
+ and on the PowerPC, the expression [(x >> 6) & 0xFF] can be turned
+ into a "rotate and mask" instruction.
- In more general terms, the purpose of the smart constructors is twofold:
-- Perform instruction selection (for operators, loads, stores and
- conditional expressions);
-- Abstract over processor dependencies in operators and addressing modes,
- providing Cminor providers with processor-independent ways of constructing
- Cminor terms.
-*)
+ Instruction selection proceeds by bottom-up rewriting over expressions.
+ The source language is Cminor and the target language is CminorSel. *)
Require Import Coqlib.
-Require Import Compare_dec.
Require Import Maps.
Require Import AST.
Require Import Integers.
Require Import Floats.
Require Import Values.
Require Import Mem.
-Require Import Op.
Require Import Globalenvs.
-Require Import Cminor.
+Require Cminor.
+Require Import Op.
+Require Import CminorSel.
-Infix ":::" := Econs (at level 60, right associativity) : cminor_scope.
+Infix ":::" := Econs (at level 60, right associativity) : selection_scope.
-Open Scope cminor_scope.
+Open Local Scope selection_scope.
(** * Lifting of let-bound variables *)
-(** Some of the smart constructors, as well as the Cminor producers,
- generate [Elet] constructs to share the evaluation of a subexpression.
- Owing to the use of de Bruijn indices for let-bound variables,
- we need to shift de Bruijn indices when an expression [b] is put
- in a [Elet a b] context. *)
+(** Some of the instruction functions generate [Elet] constructs to
+ share the evaluation of a subexpression. Owing to the use of de
+ Bruijn indices for let-bound variables, we need to shift de Bruijn
+ indices when an expression [b] is put in a [Elet a b] context. *)
Fixpoint lift_expr (p: nat) (a: expr) {struct a}: expr :=
match a with
@@ -79,12 +69,19 @@ Definition lift (a: expr): expr := lift_expr O a.
(** * Smart constructors for operators *)
-Definition negint (e: expr) := Eop (Osubimm Int.zero) (e ::: Enil).
-Definition negfloat (e: expr) := Eop Onegf (e ::: Enil).
-Definition absfloat (e: expr) := Eop Oabsf (e ::: Enil).
-Definition intoffloat (e: expr) := Eop Ointoffloat (e ::: Enil).
-Definition floatofint (e: expr) := Eop Ofloatofint (e ::: Enil).
-Definition floatofintu (e: expr) := Eop Ofloatofintu (e ::: Enil).
+(** This section defines functions for building CminorSel expressions
+ and statements, especially expressions consisting of operator
+ applications. These functions examine their arguments to choose
+ cheaper forms of operators whenever possible.
+
+ For instance, [add e1 e2] will return a CminorSel expression semantically
+ equivalent to [Eop Oadd (e1 ::: e2 ::: Enil)], but will use a
+ [Oaddimm] operator if one of the arguments is an integer constant,
+ or suppress the addition altogether if one of the arguments is the
+ null integer. In passing, we perform operator reassociation
+ ([(e + c1) * c2] becomes [(e * c2) + (c1 * c2)]) and a small amount
+ of constant propagation.
+*)
(** ** Integer logical negation *)
@@ -129,7 +126,7 @@ Inductive notint_cases: forall (e: expr), Set :=
notint_cases e.
(** We then define a classification function that takes an expression
- and return in which case it falls. Note that the catch-all case
+ and return the case in which it falls. Note that the catch-all case
[notint_default] does not state that it is mutually exclusive with
the first three, more specific cases. The classification function
nonetheless chooses the specific cases in preference to the catch-all
@@ -174,7 +171,7 @@ Definition notint (e: expr) :=
(** ** Boolean negation *)
Definition notbool_base (e: expr) :=
- Eop (Ocmp (Ccompuimm Ceq Int.zero)) (e ::: Enil).
+ Eop (Ocmp (Ccompimm Ceq Int.zero)) (e ::: Enil).
Fixpoint notbool (e: expr) {struct e} : expr :=
match e with
@@ -672,8 +669,6 @@ Definition or (e1: expr) (e2: expr) :=
Eop Oor (e1:::e2:::Enil)
end.
-Definition xor (e1 e2: expr) := Eop Oxor (e1:::e2:::Enil).
-
(** ** General shifts *)
Inductive shift_cases: forall (e1: expr), Set :=
@@ -700,9 +695,6 @@ Definition shl (e1: expr) (e2: expr) :=
Eop Oshl (e1:::e2:::Enil)
end.
-Definition shr (e1 e2: expr) :=
- Eop Oshr (e1:::e2:::Enil).
-
Definition shru (e1: expr) (e2: expr) :=
match shift_match e2 with
| shift_case1 n2 =>
@@ -791,9 +783,6 @@ Definition subf (e1: expr) (e2: expr) :=
Eop Osubf (e1:::e2:::Enil)
end.
-Definition mulf (e1 e2: expr) := Eop Omulf (e1:::e2:::Enil).
-Definition divf (e1 e2: expr) := Eop Odivf (e1:::e2:::Enil).
-
(** ** Truncations and sign extensions *)
Inductive cast8signed_cases: forall (e1: expr), Set :=
@@ -906,14 +895,7 @@ Definition singleoffloat (e: expr) :=
| singleoffloat_default e1 => Eop Osingleoffloat (e1 ::: Enil)
end.
-(** ** Comparisons and conditional expressions *)
-
-Definition cmp (c: comparison) (e1 e2: expr) :=
- Eop (Ocmp (Ccomp c)) (e1:::e2:::Enil).
-Definition cmpu (c: comparison) (e1 e2: expr) :=
- Eop (Ocmp (Ccompu c)) (e1:::e2:::Enil).
-Definition cmpf (c: comparison) (e1 e2: expr) :=
- Eop (Ocmp (Ccompf c)) (e1:::e2:::Enil).
+(** ** Conditional expressions *)
Fixpoint condexpr_of_expr (e: expr) : condexpr :=
match e with
@@ -922,12 +904,9 @@ Fixpoint condexpr_of_expr (e: expr) : condexpr :=
| Eop (Ocmp c) el => CEcond c el
| Econdition e1 e2 e3 =>
CEcondition e1 (condexpr_of_expr e2) (condexpr_of_expr e3)
- | e => CEcond (Ccompuimm Cne Int.zero) (e:::Enil)
+ | e => CEcond (Ccompimm Cne Int.zero) (e:::Enil)
end.
-Definition conditionalexpr (e1 e2 e3: expr) : expr :=
- Econdition (condexpr_of_expr e1) e2 e3.
-
(** ** Recognition of addressing modes for load and store operations *)
(*
@@ -1005,7 +984,120 @@ Definition store (chunk: memory_chunk) (e1 e2: expr) :=
| (mode, args) => Estore chunk mode args e2
end.
-(** ** If-then-else statement *)
+(** * Translation from Cminor to CminorSel *)
+
+(** Instruction selection for operator applications *)
+
+Definition sel_constant (cst: Cminor.constant) : expr :=
+ match cst with
+ | Cminor.Ointconst n => Eop (Ointconst n) Enil
+ | Cminor.Ofloatconst f => Eop (Ofloatconst f) Enil
+ | Cminor.Oaddrsymbol id ofs => Eop (Oaddrsymbol id ofs) Enil
+ | Cminor.Oaddrstack ofs => Eop (Oaddrstack ofs) Enil
+ end.
+
+Definition sel_unop (op: Cminor.unary_operation) (arg: expr) : expr :=
+ match op with
+ | Cminor.Ocast8unsigned => cast8unsigned arg
+ | Cminor.Ocast8signed => cast8signed arg
+ | Cminor.Ocast16unsigned => cast16unsigned arg
+ | Cminor.Ocast16signed => cast16signed arg
+ | Cminor.Onegint => Eop (Osubimm Int.zero) (arg ::: Enil)
+ | Cminor.Onotbool => notbool arg
+ | Cminor.Onotint => notint arg
+ | Cminor.Onegf => Eop Onegf (arg ::: Enil)
+ | Cminor.Oabsf => Eop Oabsf (arg ::: Enil)
+ | Cminor.Osingleoffloat => singleoffloat arg
+ | Cminor.Ointoffloat => Eop Ointoffloat (arg ::: Enil)
+ | Cminor.Ofloatofint => Eop Ofloatofint (arg ::: Enil)
+ | Cminor.Ofloatofintu => Eop Ofloatofintu (arg ::: Enil)
+ end.
+
+Definition sel_binop (op: Cminor.binary_operation) (arg1 arg2: expr) : expr :=
+ match op with
+ | Cminor.Oadd => add arg1 arg2
+ | Cminor.Osub => sub arg1 arg2
+ | Cminor.Omul => mul arg1 arg2
+ | Cminor.Odiv => divs arg1 arg2
+ | Cminor.Odivu => divu arg1 arg2
+ | Cminor.Omod => mods arg1 arg2
+ | Cminor.Omodu => modu arg1 arg2
+ | Cminor.Oand => and arg1 arg2
+ | Cminor.Oor => or arg1 arg2
+ | Cminor.Oxor => Eop Oxor (arg1 ::: arg2 ::: Enil)
+ | Cminor.Oshl => shl arg1 arg2
+ | Cminor.Oshr => Eop Oshr (arg1 ::: arg2 ::: Enil)
+ | Cminor.Oshru => shru arg1 arg2
+ | Cminor.Oaddf => addf arg1 arg2
+ | Cminor.Osubf => subf arg1 arg2
+ | Cminor.Omulf => Eop Omulf (arg1 ::: arg2 ::: Enil)
+ | Cminor.Odivf => Eop Odivf (arg1 ::: arg2 ::: Enil)
+ | Cminor.Ocmp c => Eop (Ocmp (Ccomp c)) (arg1 ::: arg2 ::: Enil)
+ | Cminor.Ocmpu c => Eop (Ocmp (Ccompu c)) (arg1 ::: arg2 ::: Enil)
+ | Cminor.Ocmpf c => Eop (Ocmp (Ccompf c)) (arg1 ::: arg2 ::: Enil)
+ end.
+
+(** Conversion from Cminor expression to Cminorsel expressions *)
+
+Fixpoint sel_expr (a: Cminor.expr) : expr :=
+ match a with
+ | Cminor.Evar id => Evar id
+ | Cminor.Econst cst => sel_constant cst
+ | Cminor.Eunop op arg => sel_unop op (sel_expr arg)
+ | Cminor.Ebinop op arg1 arg2 => sel_binop op (sel_expr arg1) (sel_expr arg2)
+ | Cminor.Eload chunk addr => load chunk (sel_expr addr)
+ | Cminor.Estore chunk addr rhs => store chunk (sel_expr addr) (sel_expr rhs)
+ | Cminor.Ecall sg fn args => Ecall sg (sel_expr fn) (sel_exprlist args)
+ | Cminor.Econdition cond ifso ifnot =>
+ Econdition (condexpr_of_expr (sel_expr cond))
+ (sel_expr ifso) (sel_expr ifnot)
+ | Cminor.Elet b c => Elet (sel_expr b) (sel_expr c)
+ | Cminor.Eletvar n => Eletvar n
+ | Cminor.Ealloc b => Ealloc (sel_expr b)
+ end
+
+with sel_exprlist (al: Cminor.exprlist) : exprlist :=
+ match al with
+ | Cminor.Enil => Enil
+ | Cminor.Econs a bl => Econs (sel_expr a) (sel_exprlist bl)
+ end.
+
+(** Conversion from Cminor statements to Cminorsel statements. *)
+
+Fixpoint sel_stmt (s: Cminor.stmt) : stmt :=
+ match s with
+ | Cminor.Sskip => Sskip
+ | Cminor.Sexpr e => Sexpr (sel_expr e)
+ | Cminor.Sassign id e => Sassign id (sel_expr e)
+ | Cminor.Sseq s1 s2 => Sseq (sel_stmt s1) (sel_stmt s2)
+ | Cminor.Sifthenelse e ifso ifnot =>
+ Sifthenelse (condexpr_of_expr (sel_expr e))
+ (sel_stmt ifso) (sel_stmt ifnot)
+ | Cminor.Sloop body => Sloop (sel_stmt body)
+ | Cminor.Sblock body => Sblock (sel_stmt body)
+ | Cminor.Sexit n => Sexit n
+ | Cminor.Sswitch e cases dfl => Sswitch (sel_expr e) cases dfl
+ | Cminor.Sreturn None => Sreturn None
+ | Cminor.Sreturn (Some e) => Sreturn (Some (sel_expr e))
+ | Cminor.Stailcall sg fn args =>
+ Stailcall sg (sel_expr fn) (sel_exprlist args)
+ end.
+
+(** Conversion of functions and programs. *)
+
+Definition sel_function (f: Cminor.function) : function :=
+ mkfunction
+ f.(Cminor.fn_sig)
+ f.(Cminor.fn_params)
+ f.(Cminor.fn_vars)
+ f.(Cminor.fn_stackspace)
+ (sel_stmt f.(Cminor.fn_body)).
+
+Definition sel_fundef (f: Cminor.fundef) : fundef :=
+ transf_fundef sel_function f.
+
+Definition sel_program (p: Cminor.program) : program :=
+ transform_program sel_fundef p.
+
+
-Definition ifthenelse (e: expr) (ifso ifnot: stmt) : stmt :=
- Sifthenelse (condexpr_of_expr e) ifso ifnot.
diff --git a/backend/Cmconstrproof.v b/backend/Selectionproof.v
index 35b3d8a..e41765a 100644
--- a/backend/Cmconstrproof.v
+++ b/backend/Selectionproof.v
@@ -1,15 +1,6 @@
-(** Correctness of the Cminor smart constructors. This file states
- evaluation rules for the smart constructors, for instance that [add
- a b] evaluates to [Vint(Int.add i j)] if [a] evaluates to [Vint i]
- and [b] to [Vint j]. It then proves that these rules are
- admissible, that is, satisfied for all possible choices of [a] and
- [b]. The Cminor producer can then use these evaluation rules
- (theorems) to reason about the execution of terms produced by the
- smart constructors.
-*)
+(** Correctness of instruction selection *)
Require Import Coqlib.
-Require Import Compare_dec.
Require Import Maps.
Require Import AST.
Require Import Integers.
@@ -17,14 +8,17 @@ Require Import Floats.
Require Import Values.
Require Import Mem.
Require Import Events.
-Require Import Op.
Require Import Globalenvs.
Require Import Cminor.
-Require Import Cmconstr.
+Require Import Op.
+Require Import CminorSel.
+Require Import Selection.
+
+Open Local Scope selection_scope.
Section CMCONSTR.
-Variable ge: Cminor.genv.
+Variable ge: genv.
(** * Lifting of let-bound variables *)
@@ -150,19 +144,18 @@ Hint Resolve eval_lift: evalexpr.
(** * Useful lemmas and tactics *)
-Ltac EvalOp := eapply eval_Eop; eauto with evalexpr.
-
-Ltac TrivialOp cstr :=
- unfold cstr; intros; EvalOp.
-
(** The following are trivial lemmas and custom tactics that help
perform backward (inversion) and forward reasoning over the evaluation
of operator applications. *)
+Ltac EvalOp := eapply eval_Eop; eauto with evalexpr.
+
+Ltac TrivialOp cstr := unfold cstr; intros; EvalOp.
+
Lemma inv_eval_Eop_0:
forall sp le e m1 op t m2 v,
eval_expr ge sp le e m1 (Eop op Enil) t m2 v ->
- t = E0 /\ m2 = m1 /\ eval_operation ge sp op nil = Some v.
+ t = E0 /\ m2 = m1 /\ eval_operation ge sp op nil m1 = Some v.
Proof.
intros. inversion H. inversion H6.
intuition. congruence.
@@ -173,7 +166,7 @@ Lemma inv_eval_Eop_1:
eval_expr ge sp le e m1 (Eop op (a1 ::: Enil)) t m2 v ->
exists v1,
eval_expr ge sp le e m1 a1 t m2 v1 /\
- eval_operation ge sp op (v1 :: nil) = Some v.
+ eval_operation ge sp op (v1 :: nil) m2 = Some v.
Proof.
intros.
inversion H. inversion H6. inversion H18.
@@ -187,7 +180,7 @@ Lemma inv_eval_Eop_2:
eval_expr ge sp le e m1 a1 t1 m2 v1 /\
eval_expr ge sp le e m2 a2 t2 m3 v2 /\
t3 = t1 ** t2 /\
- eval_operation ge sp op (v1 :: v2 :: nil) = Some v.
+ eval_operation ge sp op (v1 :: v2 :: nil) m3 = Some v.
Proof.
intros.
inversion H. subst. inversion H6. subst. inversion H8. subst.
@@ -229,9 +222,16 @@ Ltac SimplEval :=
Ltac InvEval H :=
generalize H; SimplEval; clear H.
-(** ** Admissible evaluation rules for the smart constructors *)
+(** * Correctness of the smart constructors *)
-(** All proofs follow a common pattern:
+(** We now show that the code generated by "smart constructor" functions
+ such as [Selection.notint] behaves as expected. Continuing the
+ [notint] example, we show that if the expression [e]
+ evaluates to some integer value [Vint n], then [Selection.notint e]
+ evaluates to a value [Vint (Int.not n)] which is indeed the integer
+ negation of the value of [e].
+
+ All proofs follow a common pattern:
- Reasoning by case over the result of the classification functions
(such as [add_match] for integer addition), gathering additional
information on the shape of the argument expressions in the non-default
@@ -244,55 +244,7 @@ Ltac InvEval H :=
by the smart constructor.
*)
-Theorem eval_negint:
- forall sp le e m1 a t m2 x,
- eval_expr ge sp le e m1 a t m2 (Vint x) ->
- eval_expr ge sp le e m1 (negint a) t m2 (Vint (Int.neg x)).
-Proof.
- TrivialOp negint.
-Qed.
-
-Theorem eval_negfloat:
- forall sp le e m1 a t m2 x,
- eval_expr ge sp le e m1 a t m2 (Vfloat x) ->
- eval_expr ge sp le e m1 (negfloat a) t m2 (Vfloat (Float.neg x)).
-Proof.
- TrivialOp negfloat.
-Qed.
-
-Theorem eval_absfloat:
- forall sp le e m1 a t m2 x,
- eval_expr ge sp le e m1 a t m2 (Vfloat x) ->
- eval_expr ge sp le e m1 (absfloat a) t m2 (Vfloat (Float.abs x)).
-Proof.
- TrivialOp absfloat.
-Qed.
-
-Theorem eval_intoffloat:
- forall sp le e m1 a t m2 x,
- eval_expr ge sp le e m1 a t m2 (Vfloat x) ->
- eval_expr ge sp le e m1 (intoffloat a) t m2 (Vint (Float.intoffloat x)).
-Proof.
- TrivialOp intoffloat.
-Qed.
-
-Theorem eval_floatofint:
- forall sp le e m1 a t m2 x,
- eval_expr ge sp le e m1 a t m2 (Vint x) ->
- eval_expr ge sp le e m1 (floatofint a) t m2 (Vfloat (Float.floatofint x)).
-Proof.
- TrivialOp floatofint.
-Qed.
-
-Theorem eval_floatofintu:
- forall sp le e m1 a t m2 x,
- eval_expr ge sp le e m1 a t m2 (Vint x) ->
- eval_expr ge sp le e m1 (floatofintu a) t m2 (Vfloat (Float.floatofintu x)).
-Proof.
- TrivialOp floatofintu.
-Qed.
-
-Theorem eval_notint:
+Lemma eval_notint:
forall sp le e m1 a t m2 x,
eval_expr ge sp le e m1 a t m2 (Vint x) ->
eval_expr ge sp le e m1 (notint a) t m2 (Vint (Int.not x)).
@@ -325,7 +277,7 @@ Qed.
Hint Resolve Val.bool_of_true_val Val.bool_of_false_val
Val.bool_of_true_val_inv Val.bool_of_false_val_inv: valboolof.
-Theorem eval_notbool:
+Lemma eval_notbool:
forall a sp le e m1 t m2 v b,
eval_expr ge sp le e m1 a t m2 v ->
Val.bool_of_val v b ->
@@ -349,11 +301,11 @@ Proof.
inversion H. subst.
simpl in H11. eapply eval_Eop; eauto.
- simpl. caseEq (eval_condition c vl); intros.
+ simpl. caseEq (eval_condition c vl m2); intros.
rewrite H1 in H11.
assert (b0 = b).
destruct b0; inversion H11; subst v; inversion H0; auto.
- subst b0. rewrite (Op.eval_negate_condition _ _ H1).
+ subst b0. rewrite (Op.eval_negate_condition _ _ _ H1).
destruct b; reflexivity.
rewrite H1 in H11; discriminate.
@@ -364,7 +316,7 @@ Proof.
destruct v4; eauto. auto.
Qed.
-Theorem eval_addimm:
+Lemma eval_addimm:
forall sp le e m1 n a t m2 x,
eval_expr ge sp le e m1 a t m2 (Vint x) ->
eval_expr ge sp le e m1 (addimm n a) t m2 (Vint (Int.add x n)).
@@ -382,7 +334,7 @@ Proof.
EvalOp.
Qed.
-Theorem eval_addimm_ptr:
+Lemma eval_addimm_ptr:
forall sp le e m1 n t a m2 b ofs,
eval_expr ge sp le e m1 a t m2 (Vptr b ofs) ->
eval_expr ge sp le e m1 (addimm n a) t m2 (Vptr b (Int.add ofs n)).
@@ -404,7 +356,7 @@ Proof.
EvalOp.
Qed.
-Theorem eval_add:
+Lemma eval_add:
forall sp le e m1 a t1 m2 x b t2 m3 y,
eval_expr ge sp le e m1 a t1 m2 (Vint x) ->
eval_expr ge sp le e m2 b t2 m3 (Vint y) ->
@@ -431,7 +383,7 @@ Proof.
EvalOp.
Qed.
-Theorem eval_add_ptr:
+Lemma eval_add_ptr:
forall sp le e m1 a t1 m2 p x b t2 m3 y,
eval_expr ge sp le e m1 a t1 m2 (Vptr p x) ->
eval_expr ge sp le e m2 b t2 m3 (Vint y) ->
@@ -456,7 +408,7 @@ Proof.
EvalOp.
Qed.
-Theorem eval_add_ptr_2:
+Lemma eval_add_ptr_2:
forall sp le e m1 a t1 m2 p x b t2 m3 y,
eval_expr ge sp le e m1 a t1 m2 (Vint x) ->
eval_expr ge sp le e m2 b t2 m3 (Vptr p y) ->
@@ -483,7 +435,7 @@ Proof.
EvalOp.
Qed.
-Theorem eval_sub:
+Lemma eval_sub:
forall sp le e m1 a t1 m2 x b t2 m3 y,
eval_expr ge sp le e m1 a t1 m2 (Vint x) ->
eval_expr ge sp le e m2 b t2 m3 (Vint y) ->
@@ -511,7 +463,7 @@ Proof.
EvalOp.
Qed.
-Theorem eval_sub_ptr_int:
+Lemma eval_sub_ptr_int:
forall sp le e m1 a t1 m2 p x b t2 m3 y,
eval_expr ge sp le e m1 a t1 m2 (Vptr p x) ->
eval_expr ge sp le e m2 b t2 m3 (Vint y) ->
@@ -540,7 +492,7 @@ Proof.
EvalOp.
Qed.
-Theorem eval_sub_ptr_ptr:
+Lemma eval_sub_ptr_ptr:
forall sp le e m1 a t1 m2 p x b t2 m3 y,
eval_expr ge sp le e m1 a t1 m2 (Vptr p x) ->
eval_expr ge sp le e m2 b t2 m3 (Vptr p y) ->
@@ -589,7 +541,7 @@ Proof.
EvalOp.
Qed.
-Theorem eval_shlimm:
+Lemma eval_shlimm:
forall sp le e m1 a n t m2 x,
eval_expr ge sp le e m1 a t m2 (Vint x) ->
Int.ltu n (Int.repr 32) = true ->
@@ -603,7 +555,7 @@ Proof.
apply eval_rolm. auto. symmetry. apply Int.shl_rolm. exact H0.
Qed.
-Theorem eval_shruimm:
+Lemma eval_shruimm:
forall sp le e m1 a n t m2 x,
eval_expr ge sp le e m1 a t m2 (Vint x) ->
Int.ltu n (Int.repr 32) = true ->
@@ -649,7 +601,7 @@ Proof.
intros. EvalOp.
Qed.
-Theorem eval_mulimm:
+Lemma eval_mulimm:
forall sp le e m1 a n t m2 x,
eval_expr ge sp le e m1 a t m2 (Vint x) ->
eval_expr ge sp le e m1 (mulimm n a) t m2 (Vint (Int.mul x n)).
@@ -669,7 +621,7 @@ Proof.
apply eval_mulimm_base. assumption.
Qed.
-Theorem eval_mul:
+Lemma eval_mul:
forall sp le e m1 a t1 m2 x b t2 m3 y,
eval_expr ge sp le e m1 a t1 m2 (Vint x) ->
eval_expr ge sp le e m2 b t2 m3 (Vint y) ->
@@ -683,7 +635,7 @@ Proof.
EvalOp.
Qed.
-Theorem eval_divs:
+Lemma eval_divs:
forall sp le e m1 a t1 m2 x b t2 m3 y,
eval_expr ge sp le e m1 a t1 m2 (Vint x) ->
eval_expr ge sp le e m2 b t2 m3 (Vint y) ->
@@ -696,9 +648,9 @@ Qed.
Lemma eval_mod_aux:
forall divop semdivop,
- (forall sp x y,
+ (forall sp x y m,
y <> Int.zero ->
- eval_operation ge sp divop (Vint x :: Vint y :: nil) =
+ eval_operation ge sp divop (Vint x :: Vint y :: nil) m =
Some (Vint (semdivop x y))) ->
forall sp le e m1 a t1 m2 x b t2 m3 y,
eval_expr ge sp le e m1 a t1 m2 (Vint x) ->
@@ -725,7 +677,7 @@ Proof.
reflexivity. traceEq.
Qed.
-Theorem eval_mods:
+Lemma eval_mods:
forall sp le e m1 a t1 m2 x b t2 m3 y,
eval_expr ge sp le e m1 a t1 m2 (Vint x) ->
eval_expr ge sp le e m2 b t2 m3 (Vint y) ->
@@ -750,7 +702,7 @@ Proof.
predSpec Int.eq Int.eq_spec y Int.zero. contradiction. auto.
Qed.
-Theorem eval_divu:
+Lemma eval_divu:
forall sp le e m1 a t1 m2 x b t2 m3 y,
eval_expr ge sp le e m1 a t1 m2 (Vint x) ->
eval_expr ge sp le e m2 b t2 m3 (Vint y) ->
@@ -767,7 +719,7 @@ Proof.
eapply eval_divu_base; eauto.
Qed.
-Theorem eval_modu:
+Lemma eval_modu:
forall sp le e m1 a t1 m2 x b t2 m3 y,
eval_expr ge sp le e m1 a t1 m2 (Vint x) ->
eval_expr ge sp le e m2 b t2 m3 (Vint y) ->
@@ -788,7 +740,7 @@ Proof.
eexact H. eexact H0. auto. auto.
Qed.
-Theorem eval_andimm:
+Lemma eval_andimm:
forall sp le e m1 n a t m2 x,
eval_expr ge sp le e m1 a t m2 (Vint x) ->
eval_expr ge sp le e m1 (andimm n a) t m2 (Vint (Int.and x n)).
@@ -798,7 +750,7 @@ Proof.
EvalOp.
Qed.
-Theorem eval_and:
+Lemma eval_and:
forall sp le e m1 a t1 m2 x b t2 m3 y,
eval_expr ge sp le e m1 a t1 m2 (Vint x) ->
eval_expr ge sp le e m2 b t2 m3 (Vint y) ->
@@ -848,14 +800,7 @@ Proof.
EvalOp.
Qed.
-Theorem eval_xor:
- forall sp le e m1 a t1 m2 x b t2 m3 y,
- eval_expr ge sp le e m1 a t1 m2 (Vint x) ->
- eval_expr ge sp le e m2 b t2 m3 (Vint y) ->
- eval_expr ge sp le e m1 (xor a b) (t1**t2) m3 (Vint (Int.xor x y)).
-Proof. TrivialOp xor. Qed.
-
-Theorem eval_shl:
+Lemma eval_shl:
forall sp le e m1 a t1 m2 x b t2 m3 y,
eval_expr ge sp le e m1 a t1 m2 (Vint x) ->
eval_expr ge sp le e m2 b t2 m3 (Vint y) ->
@@ -867,17 +812,7 @@ Proof.
EvalOp. simpl. rewrite H1. auto.
Qed.
-Theorem eval_shr:
- forall sp le e m1 a t1 m2 x b t2 m3 y,
- eval_expr ge sp le e m1 a t1 m2 (Vint x) ->
- eval_expr ge sp le e m2 b t2 m3 (Vint y) ->
- Int.ltu y (Int.repr 32) = true ->
- eval_expr ge sp le e m1 (shr a b) (t1**t2) m3 (Vint (Int.shr x y)).
-Proof.
- TrivialOp shr. simpl. rewrite H1. auto.
-Qed.
-
-Theorem eval_shru:
+Lemma eval_shru:
forall sp le e m1 a t1 m2 x b t2 m3 y,
eval_expr ge sp le e m1 a t1 m2 (Vint x) ->
eval_expr ge sp le e m2 b t2 m3 (Vint y) ->
@@ -889,7 +824,7 @@ Proof.
EvalOp. simpl. rewrite H1. auto.
Qed.
-Theorem eval_addf:
+Lemma eval_addf:
forall sp le e m1 a t1 m2 x b t2 m3 y,
eval_expr ge sp le e m1 a t1 m2 (Vfloat x) ->
eval_expr ge sp le e m2 b t2 m3 (Vfloat y) ->
@@ -908,7 +843,7 @@ Proof.
EvalOp.
Qed.
-Theorem eval_subf:
+Lemma eval_subf:
forall sp le e m1 a t1 m2 x b t2 m3 y,
eval_expr ge sp le e m1 a t1 m2 (Vfloat x) ->
eval_expr ge sp le e m2 b t2 m3 (Vfloat y) ->
@@ -921,21 +856,7 @@ Proof.
EvalOp.
Qed.
-Theorem eval_mulf:
- forall sp le e m1 a t1 m2 x b t2 m3 y,
- eval_expr ge sp le e m1 a t1 m2 (Vfloat x) ->
- eval_expr ge sp le e m2 b t2 m3 (Vfloat y) ->
- eval_expr ge sp le e m1 (mulf a b) (t1**t2) m3 (Vfloat (Float.mul x y)).
-Proof. TrivialOp mulf. Qed.
-
-Theorem eval_divf:
- forall sp le e m1 a t1 m2 x b t2 m3 y,
- eval_expr ge sp le e m1 a t1 m2 (Vfloat x) ->
- eval_expr ge sp le e m2 b t2 m3 (Vfloat y) ->
- eval_expr ge sp le e m1 (divf a b) (t1**t2) m3 (Vfloat (Float.div x y)).
-Proof. TrivialOp divf. Qed.
-
-Theorem eval_cast8signed:
+Lemma eval_cast8signed:
forall sp le e m1 a t m2 v,
eval_expr ge sp le e m1 a t m2 v ->
eval_expr ge sp le e m1 (cast8signed a) t m2 (Val.cast8signed v).
@@ -946,7 +867,7 @@ Proof.
EvalOp.
Qed.
-Theorem eval_cast8unsigned:
+Lemma eval_cast8unsigned:
forall sp le e m1 a t m2 v,
eval_expr ge sp le e m1 a t m2 v ->
eval_expr ge sp le e m1 (cast8unsigned a) t m2 (Val.cast8unsigned v).
@@ -957,7 +878,7 @@ Proof.
EvalOp.
Qed.
-Theorem eval_cast16signed:
+Lemma eval_cast16signed:
forall sp le e m1 a t m2 v,
eval_expr ge sp le e m1 a t m2 v ->
eval_expr ge sp le e m1 (cast16signed a) t m2 (Val.cast16signed v).
@@ -968,7 +889,7 @@ Proof.
EvalOp.
Qed.
-Theorem eval_cast16unsigned:
+Lemma eval_cast16unsigned:
forall sp le e m1 a t m2 v,
eval_expr ge sp le e m1 a t m2 v ->
eval_expr ge sp le e m1 (cast16unsigned a) t m2 (Val.cast16unsigned v).
@@ -979,7 +900,7 @@ Proof.
EvalOp.
Qed.
-Theorem eval_singleoffloat:
+Lemma eval_singleoffloat:
forall sp le e m1 a t m2 v,
eval_expr ge sp le e m1 a t m2 v ->
eval_expr ge sp le e m1 (singleoffloat a) t m2 (Val.singleoffloat v).
@@ -990,75 +911,12 @@ Proof.
EvalOp.
Qed.
-Theorem eval_cmp:
- forall sp le c e m1 a t1 m2 x b t2 m3 y,
- eval_expr ge sp le e m1 a t1 m2 (Vint x) ->
- eval_expr ge sp le e m2 b t2 m3 (Vint y) ->
- eval_expr ge sp le e m1 (cmp c a b) (t1**t2) m3 (Val.of_bool (Int.cmp c x y)).
-Proof.
- TrivialOp cmp.
- simpl. case (Int.cmp c x y); auto.
-Qed.
-
-Theorem eval_cmp_null_r:
- forall sp le c e m1 a t1 m2 p x b t2 m3 v,
- eval_expr ge sp le e m1 a t1 m2 (Vptr p x) ->
- eval_expr ge sp le e m2 b t2 m3 (Vint Int.zero) ->
- (c = Ceq /\ v = Vfalse) \/ (c = Cne /\ v = Vtrue) ->
- eval_expr ge sp le e m1 (cmp c a b) (t1**t2) m3 v.
-Proof.
- TrivialOp cmp.
- simpl. elim H1; intros [EQ1 EQ2]; subst c; subst v; reflexivity.
-Qed.
-
-Theorem eval_cmp_null_l:
- forall sp le c e m1 a t1 m2 p x b t2 m3 v,
- eval_expr ge sp le e m1 a t1 m2 (Vint Int.zero) ->
- eval_expr ge sp le e m2 b t2 m3 (Vptr p x) ->
- (c = Ceq /\ v = Vfalse) \/ (c = Cne /\ v = Vtrue) ->
- eval_expr ge sp le e m1 (cmp c a b) (t1**t2) m3 v.
-Proof.
- TrivialOp cmp.
- simpl. elim H1; intros [EQ1 EQ2]; subst c; subst v; reflexivity.
-Qed.
-
-Theorem eval_cmp_ptr:
- forall sp le c e m1 a t1 m2 p x b t2 m3 y,
- eval_expr ge sp le e m1 a t1 m2 (Vptr p x) ->
- eval_expr ge sp le e m2 b t2 m3 (Vptr p y) ->
- eval_expr ge sp le e m1 (cmp c a b) (t1**t2) m3 (Val.of_bool (Int.cmp c x y)).
-Proof.
- TrivialOp cmp.
- simpl. unfold eq_block. rewrite zeq_true.
- case (Int.cmp c x y); auto.
-Qed.
-
-Theorem eval_cmpu:
- forall sp le c e m1 a t1 m2 x b t2 m3 y,
- eval_expr ge sp le e m1 a t1 m2 (Vint x) ->
- eval_expr ge sp le e m2 b t2 m3 (Vint y) ->
- eval_expr ge sp le e m1 (cmpu c a b) (t1**t2) m3 (Val.of_bool (Int.cmpu c x y)).
-Proof.
- TrivialOp cmpu.
- simpl. case (Int.cmpu c x y); auto.
-Qed.
-
-Theorem eval_cmpf:
- forall sp le c e m1 a t1 m2 x b t2 m3 y,
- eval_expr ge sp le e m1 a t1 m2 (Vfloat x) ->
- eval_expr ge sp le e m2 b t2 m3 (Vfloat y) ->
- eval_expr ge sp le e m1 (cmpf c a b) (t1**t2) m3 (Val.of_bool (Float.cmp c x y)).
-Proof.
- TrivialOp cmpf.
- simpl. case (Float.cmp c x y); auto.
-Qed.
-
Lemma eval_base_condition_of_expr:
forall sp le a e m1 t m2 v (b: bool),
eval_expr ge sp le e m1 a t m2 v ->
Val.bool_of_val v b ->
eval_condexpr ge sp le e m1
- (CEcond (Ccompuimm Cne Int.zero) (a ::: Enil))
+ (CEcond (Ccompimm Cne Int.zero) (a ::: Enil))
t m2 b.
Proof.
intros.
@@ -1090,30 +948,6 @@ Proof.
destruct v1; eauto with evalexpr.
Qed.
-Theorem eval_conditionalexpr_true:
- forall sp le e m1 a1 t1 m2 v1 t2 a2 m3 v2 a3,
- eval_expr ge sp le e m1 a1 t1 m2 v1 ->
- Val.is_true v1 ->
- eval_expr ge sp le e m2 a2 t2 m3 v2 ->
- eval_expr ge sp le e m1 (conditionalexpr a1 a2 a3) (t1**t2) m3 v2.
-Proof.
- intros; unfold conditionalexpr.
- apply eval_Econdition with t1 m2 true t2; auto.
- eapply eval_condition_of_expr; eauto with valboolof.
-Qed.
-
-Theorem eval_conditionalexpr_false:
- forall sp le e m1 a1 t1 m2 v1 a2 t2 m3 v2 a3,
- eval_expr ge sp le e m1 a1 t1 m2 v1 ->
- Val.is_false v1 ->
- eval_expr ge sp le e m2 a3 t2 m3 v2 ->
- eval_expr ge sp le e m1 (conditionalexpr a1 a2 a3) (t1**t2) m3 v2.
-Proof.
- intros; unfold conditionalexpr.
- apply eval_Econdition with t1 m2 false t2; auto.
- eapply eval_condition_of_expr; eauto with valboolof.
-Qed.
-
Lemma eval_addressing:
forall sp le e m1 a t m2 v b ofs,
eval_expr ge sp le e m1 a t m2 v ->
@@ -1150,7 +984,7 @@ Proof.
subst v. simpl. rewrite Int.add_zero. auto.
Qed.
-Theorem eval_load:
+Lemma eval_load:
forall sp le e m1 a t m2 v chunk v',
eval_expr ge sp le e m1 a t m2 v ->
Mem.loadv chunk m2 v = Some v' ->
@@ -1163,7 +997,7 @@ Proof.
eapply eval_Eload; eauto.
Qed.
-Theorem eval_store:
+Lemma eval_store:
forall sp le e m1 a1 t1 m2 v1 a2 t2 m3 v2 chunk m4,
eval_expr ge sp le e m1 a1 t1 m2 v1 ->
eval_expr ge sp le e m2 a2 t2 m3 v2 ->
@@ -1177,31 +1011,230 @@ Proof.
eapply eval_Estore; eauto.
Qed.
-Theorem exec_ifthenelse_true:
- forall sp e m1 a t1 m2 v ifso ifnot t2 e3 m3 out,
- eval_expr ge sp nil e m1 a t1 m2 v ->
- Val.is_true v ->
- exec_stmt ge sp e m2 ifso t2 e3 m3 out ->
- exec_stmt ge sp e m1 (ifthenelse a ifso ifnot) (t1**t2) e3 m3 out.
+(** * Correctness of instruction selection for operators *)
+
+(** We now prove a semantic preservation result for the [sel_unop]
+ and [sel_binop] selection functions. The proof exploits
+ the results of the previous section. *)
+
+Lemma eval_sel_unop:
+ forall sp le e m op a1 t m1 v1 v,
+ eval_expr ge sp le e m a1 t m1 v1 ->
+ eval_unop op v1 = Some v ->
+ eval_expr ge sp le e m (sel_unop op a1) t m1 v.
Proof.
- intros. unfold ifthenelse.
- apply exec_Sifthenelse with t1 m2 true t2.
- eapply eval_condition_of_expr; eauto with valboolof.
- auto. auto.
+ destruct op; simpl; intros; FuncInv; try subst v.
+ apply eval_cast8unsigned; auto.
+ apply eval_cast8signed; auto.
+ apply eval_cast16unsigned; auto.
+ apply eval_cast16signed; auto.
+ EvalOp.
+ generalize (Int.eq_spec i Int.zero). destruct (Int.eq i Int.zero); intro.
+ change true with (negb false). eapply eval_notbool; eauto. subst i; constructor.
+ change false with (negb true). eapply eval_notbool; eauto. constructor; auto.
+ change Vfalse with (Val.of_bool (negb true)).
+ eapply eval_notbool; eauto. constructor.
+ apply eval_notint; auto.
+ EvalOp.
+ EvalOp.
+ apply eval_singleoffloat; auto.
+ EvalOp.
+ EvalOp.
+ EvalOp.
Qed.
-Theorem exec_ifthenelse_false:
- forall sp e m1 a t1 m2 v ifso ifnot t2 e3 m3 out,
- eval_expr ge sp nil e m1 a t1 m2 v ->
- Val.is_false v ->
- exec_stmt ge sp e m2 ifnot t2 e3 m3 out ->
- exec_stmt ge sp e m1 (ifthenelse a ifso ifnot) (t1**t2) e3 m3 out.
+Lemma eval_sel_binop:
+ forall sp le e m op a1 a2 t1 m1 v1 t2 m2 v2 v,
+ eval_expr ge sp le e m a1 t1 m1 v1 ->
+ eval_expr ge sp le e m1 a2 t2 m2 v2 ->
+ eval_binop op v1 v2 m2 = Some v ->
+ eval_expr ge sp le e m (sel_binop op a1 a2) (t1 ** t2) m2 v.
Proof.
- intros. unfold ifthenelse.
- apply exec_Sifthenelse with t1 m2 false t2.
- eapply eval_condition_of_expr; eauto with valboolof.
- auto. auto.
+ destruct op; simpl; intros; FuncInv; try subst v.
+ eapply eval_add; eauto.
+ eapply eval_add_ptr_2; eauto.
+ eapply eval_add_ptr; eauto.
+ eapply eval_sub; eauto.
+ eapply eval_sub_ptr_int; eauto.
+ destruct (eq_block b b0); inv H1.
+ eapply eval_sub_ptr_ptr; eauto.
+ eapply eval_mul; eauto.
+ generalize (Int.eq_spec i0 Int.zero). intro. destruct (Int.eq i0 Int.zero); inv H1.
+ eapply eval_divs; eauto.
+ generalize (Int.eq_spec i0 Int.zero). intro. destruct (Int.eq i0 Int.zero); inv H1.
+ eapply eval_divu; eauto.
+ generalize (Int.eq_spec i0 Int.zero). intro. destruct (Int.eq i0 Int.zero); inv H1.
+ eapply eval_mods; eauto.
+ generalize (Int.eq_spec i0 Int.zero). intro. destruct (Int.eq i0 Int.zero); inv H1.
+ eapply eval_modu; eauto.
+ eapply eval_and; eauto.
+ eapply eval_or; eauto.
+ EvalOp.
+ caseEq (Int.ltu i0 (Int.repr 32)); intro; rewrite H2 in H1; inv H1.
+ eapply eval_shl; eauto.
+ EvalOp.
+ caseEq (Int.ltu i0 (Int.repr 32)); intro; rewrite H2 in H1; inv H1.
+ eapply eval_shru; eauto.
+ eapply eval_addf; eauto.
+ eapply eval_subf; eauto.
+ EvalOp.
+ EvalOp.
+ EvalOp. simpl. destruct (Int.cmp c i i0); auto.
+ EvalOp. simpl. generalize H1; unfold eval_compare_null, Cminor.eval_compare_null.
+ destruct (Int.eq i Int.zero). destruct c; intro EQ; inv EQ; auto.
+ auto.
+ EvalOp. simpl. generalize H1; unfold eval_compare_null, Cminor.eval_compare_null.
+ destruct (Int.eq i0 Int.zero). destruct c; intro EQ; inv EQ; auto.
+ auto.
+ EvalOp. simpl.
+ destruct (valid_pointer m2 b (Int.signed i) && valid_pointer m2 b0 (Int.signed i0)).
+ destruct (eq_block b b0); inv H1.
+ destruct (Int.cmp c i i0); auto.
+ auto.
+ EvalOp. simpl. destruct (Int.cmpu c i i0); auto.
+ EvalOp. simpl. destruct (Float.cmp c f f0); auto.
Qed.
End CMCONSTR.
+(** * Semantic preservation for instruction selection. *)
+
+Section PRESERVATION.
+
+Variable prog: Cminor.program.
+Let tprog := sel_program prog.
+Let ge := Genv.globalenv prog.
+Let tge := Genv.globalenv tprog.
+
+(** Relationship between the global environments for the original
+ CminorSel program and the generated RTL program. *)
+
+Lemma symbols_preserved:
+ forall (s: ident), Genv.find_symbol tge s = Genv.find_symbol ge s.
+Proof.
+ intros; unfold ge, tge, tprog, sel_program.
+ apply Genv.find_symbol_transf.
+Qed.
+
+Lemma functions_translated:
+ forall (v: val) (f: Cminor.fundef),
+ Genv.find_funct ge v = Some f ->
+ Genv.find_funct tge v = Some (sel_fundef f).
+Proof.
+ intros.
+ exact (Genv.find_funct_transf sel_fundef H).
+Qed.
+
+Lemma function_ptr_translated:
+ forall (b: block) (f: Cminor.fundef),
+ Genv.find_funct_ptr ge b = Some f ->
+ Genv.find_funct_ptr tge b = Some (sel_fundef f).
+Proof.
+ intros.
+ exact (Genv.find_funct_ptr_transf sel_fundef H).
+Qed.
+
+Lemma sig_function_translated:
+ forall f,
+ funsig (sel_fundef f) = Cminor.funsig f.
+Proof.
+ intros. destruct f; reflexivity.
+Qed.
+
+(** This is the main semantic preservation theorem:
+ instruction selection preserves the semantics of function invocations.
+ The proof is an induction over the Cminor evaluation derivation. *)
+
+Lemma sel_function_correct:
+ forall m fd vargs t m' vres,
+ Cminor.eval_funcall ge m fd vargs t m' vres ->
+ CminorSel.eval_funcall tge m (sel_fundef fd) vargs t m' vres.
+Proof.
+ apply (Cminor.eval_funcall_ind4 ge
+ (fun sp le e m a t m' v => eval_expr tge sp le e m (sel_expr a) t m' v)
+ (fun sp le e m a t m' v => eval_exprlist tge sp le e m (sel_exprlist a) t m' v)
+ (fun m fd vargs t m' vres => eval_funcall tge m (sel_fundef fd) vargs t m' vres)
+ (fun sp e m s t e' m' out => exec_stmt tge sp e m (sel_stmt s) t e' m' out));
+ intros; simpl.
+ (* Evar *)
+ constructor; auto.
+ (* Econst *)
+ destruct cst; simpl; simpl in H; (econstructor; [constructor|simpl;auto]).
+ rewrite symbols_preserved. auto.
+ (* Eunop *)
+ eapply eval_sel_unop; eauto.
+ (* Ebinop *)
+ subst t. eapply eval_sel_binop; eauto.
+ (* Eload *)
+ eapply eval_load; eauto.
+ (* Estore *)
+ subst t. eapply eval_store; eauto.
+ (* Ecall *)
+ econstructor; eauto. apply functions_translated; auto.
+ rewrite <- H4. apply sig_function_translated.
+ (* Econdition *)
+ econstructor; eauto. eapply eval_condition_of_expr; eauto.
+ destruct b1; auto.
+ (* Elet *)
+ econstructor; eauto.
+ (* Eletvar *)
+ constructor; auto.
+ (* Ealloc *)
+ econstructor; eauto.
+ (* Enil *)
+ constructor.
+ (* Econs *)
+ econstructor; eauto.
+ (* Internal function *)
+ econstructor; eauto.
+ (* External function *)
+ econstructor; eauto.
+ (* Sskip *)
+ constructor.
+ (* Sexpr *)
+ econstructor; eauto.
+ (* Sassign *)
+ econstructor; eauto.
+ (* Sifthenelse *)
+ econstructor; eauto. eapply eval_condition_of_expr; eauto.
+ destruct b1; auto.
+ (* Sseq *)
+ eapply exec_Sseq_continue; eauto.
+ eapply exec_Sseq_stop; eauto.
+ (* Sloop *)
+ eapply exec_Sloop_loop; eauto.
+ eapply exec_Sloop_stop; eauto.
+ (* Sblock *)
+ econstructor; eauto.
+ (* Sexit *)
+ constructor.
+ (* Sswitch *)
+ econstructor; eauto.
+ (* Sreturn *)
+ constructor.
+ econstructor; eauto.
+ (* Stailcall *)
+ econstructor; eauto. apply functions_translated; auto.
+ rewrite <- H4. apply sig_function_translated.
+Qed.
+
+End PRESERVATION.
+
+(** As a corollary, instruction selection preserves the observable
+ behaviour of programs. *)
+
+Theorem sel_program_correct:
+ forall prog t r,
+ Cminor.exec_program prog t r ->
+ CminorSel.exec_program (sel_program prog) t r.
+Proof.
+ intros.
+ destruct H as [b [f [m [FINDS [FINDF [SIG EXEC]]]]]].
+ exists b; exists (sel_fundef f); exists m.
+ split. simpl. rewrite <- FINDS. apply symbols_preserved.
+ split. apply function_ptr_translated. auto.
+ split. rewrite <- SIG. apply sig_function_translated.
+ replace (Genv.init_mem (sel_program prog)) with (Genv.init_mem prog).
+ apply sel_function_correct; auto.
+ symmetry. unfold sel_program. apply Genv.init_mem_transf.
+Qed.
diff --git a/backend/Stacking.v b/backend/Stacking.v
index de350dc..c19e293 100644
--- a/backend/Stacking.v
+++ b/backend/Stacking.v
@@ -2,13 +2,14 @@
Require Import Coqlib.
Require Import Maps.
+Require Import Errors.
Require Import AST.
Require Import Integers.
Require Import Op.
Require Import RTL.
Require Import Locations.
Require Import Linear.
-Require Import Lineartyping.
+Require Import Bounds.
Require Import Mach.
Require Import Conventions.
@@ -87,43 +88,61 @@ Definition offset_of_index (fe: frame_env) (idx: frame_index) :=
store in the frame the values of callee-save registers used by the
current function. *)
-Definition save_int_callee_save (fe: frame_env) (cs: mreg) (k: Mach.code) :=
- let i := index_int_callee_save cs in
- if zlt i fe.(fe_num_int_callee_save)
- then Msetstack cs (Int.repr (offset_of_index fe (FI_saved_int i))) Tint :: k
+Definition save_callee_save_reg
+ (bound: frame_env -> Z) (number: mreg -> Z) (mkindex: Z -> frame_index)
+ (ty: typ) (fe: frame_env) (cs: mreg) (k: Mach.code) :=
+ let i := number cs in
+ if zlt i (bound fe)
+ then Msetstack cs (Int.repr (offset_of_index fe (mkindex i))) ty :: k
else k.
-Definition save_float_callee_save (fe: frame_env) (cs: mreg) (k: Mach.code) :=
- let i := index_float_callee_save cs in
- if zlt i fe.(fe_num_float_callee_save)
- then Msetstack cs (Int.repr (offset_of_index fe (FI_saved_float i))) Tfloat :: k
- else k.
+Definition save_callee_save_regs
+ (bound: frame_env -> Z) (number: mreg -> Z) (mkindex: Z -> frame_index)
+ (ty: typ) (fe: frame_env) (csl: list mreg) (k: Mach.code) :=
+ List.fold_right (save_callee_save_reg bound number mkindex ty fe) k csl.
+
+Definition save_callee_save_int (fe: frame_env) :=
+ save_callee_save_regs
+ fe_num_int_callee_save index_int_callee_save FI_saved_int
+ Tint fe int_callee_save_regs.
+
+Definition save_callee_save_float (fe: frame_env) :=
+ save_callee_save_regs
+ fe_num_float_callee_save index_float_callee_save FI_saved_float
+ Tfloat fe float_callee_save_regs.
Definition save_callee_save (fe: frame_env) (k: Mach.code) :=
- List.fold_right (save_int_callee_save fe)
- (List.fold_right (save_float_callee_save fe) k float_callee_save_regs)
- int_callee_save_regs.
+ save_callee_save_int fe (save_callee_save_float fe k).
(** [restore_callee_save fe k] adds before [k] the instructions that
re-load from the frame the values of callee-save registers used by the
current function, restoring these registers to their initial values. *)
-Definition restore_int_callee_save (fe: frame_env) (cs: mreg) (k: Mach.code) :=
- let i := index_int_callee_save cs in
- if zlt i fe.(fe_num_int_callee_save)
- then Mgetstack (Int.repr (offset_of_index fe (FI_saved_int i))) Tint cs :: k
+Definition restore_callee_save_reg
+ (bound: frame_env -> Z) (number: mreg -> Z) (mkindex: Z -> frame_index)
+ (ty: typ) (fe: frame_env) (cs: mreg) (k: Mach.code) :=
+ let i := number cs in
+ if zlt i (bound fe)
+ then Mgetstack (Int.repr (offset_of_index fe (mkindex i))) ty cs :: k
else k.
-Definition restore_float_callee_save (fe: frame_env) (cs: mreg) (k: Mach.code) :=
- let i := index_float_callee_save cs in
- if zlt i fe.(fe_num_float_callee_save)
- then Mgetstack (Int.repr (offset_of_index fe (FI_saved_float i))) Tfloat cs :: k
- else k.
+Definition restore_callee_save_regs
+ (bound: frame_env -> Z) (number: mreg -> Z) (mkindex: Z -> frame_index)
+ (ty: typ) (fe: frame_env) (csl: list mreg) (k: Mach.code) :=
+ List.fold_right (restore_callee_save_reg bound number mkindex ty fe) k csl.
+
+Definition restore_callee_save_int (fe: frame_env) :=
+ restore_callee_save_regs
+ fe_num_int_callee_save index_int_callee_save FI_saved_int
+ Tint fe int_callee_save_regs.
+
+Definition restore_callee_save_float (fe: frame_env) :=
+ restore_callee_save_regs
+ fe_num_float_callee_save index_float_callee_save FI_saved_float
+ Tfloat fe float_callee_save_regs.
Definition restore_callee_save (fe: frame_env) (k: Mach.code) :=
- List.fold_right (restore_int_callee_save fe)
- (List.fold_right (restore_float_callee_save fe) k float_callee_save_regs)
- int_callee_save_regs.
+ restore_callee_save_int fe (restore_callee_save_float fe k).
(** * Code transformation. *)
@@ -186,6 +205,8 @@ Definition transl_instr
Mstore chunk (transl_addr fe addr) args src :: k
| Lcall sig ros =>
Mcall sig ros :: k
+ | Ltailcall sig ros =>
+ restore_callee_save fe (Mtailcall sig ros :: k)
| Lalloc =>
Malloc :: k
| Llabel lbl =>
@@ -214,18 +235,23 @@ Definition transl_code
Definition transl_body (f: Linear.function) (fe: frame_env) :=
save_callee_save fe (transl_code fe f.(Linear.fn_code)).
-Definition transf_function (f: Linear.function) : option Mach.function :=
+Open Local Scope string_scope.
+
+Definition transf_function (f: Linear.function) : res Mach.function :=
let fe := make_env (function_bounds f) in
- if zlt f.(Linear.fn_stacksize) 0 then None else
- if zlt (- Int.min_signed) fe.(fe_size) then None else
- Some (Mach.mkfunction
+ if zlt f.(Linear.fn_stacksize) 0 then
+ Error (msg "Stacking.transf_function")
+ else if zlt (- Int.min_signed) fe.(fe_size) then
+ Error (msg "Too many spilled variables, stack size exceeded")
+ else
+ OK (Mach.mkfunction
f.(Linear.fn_sig)
(transl_body f fe)
f.(Linear.fn_stacksize)
fe.(fe_size)).
-Definition transf_fundef (f: Linear.fundef) : option Mach.fundef :=
+Definition transf_fundef (f: Linear.fundef) : res Mach.fundef :=
AST.transf_partial_fundef transf_function f.
-Definition transf_program (p: Linear.program) : option Mach.program :=
+Definition transf_program (p: Linear.program) : res Mach.program :=
transform_partial_program transf_fundef p.
diff --git a/backend/Stackingproof.v b/backend/Stackingproof.v
index 3bc4339..905570e 100644
--- a/backend/Stackingproof.v
+++ b/backend/Stackingproof.v
@@ -1,15 +1,16 @@
(** Correctness proof for the translation from Linear to Mach. *)
(** This file proves semantic preservation for the [Stacking] pass.
- For the target language Mach, we use the alternate semantics
+ For the target language Mach, we use the abstract semantics
given in file [Machabstr], where a part of the activation record
is not resident in memory. Combined with the semantic equivalence
- result between the two Mach semantics (see file [Machabstr2mach]),
+ result between the two Mach semantics (see file [Machabstr2concr]),
the proof in this file also shows semantic preservation with
- respect to the standard Mach semantics. *)
+ respect to the concrete Mach semantics. *)
Require Import Coqlib.
Require Import Maps.
+Require Import Errors.
Require Import AST.
Require Import Integers.
Require Import Values.
@@ -17,11 +18,13 @@ Require Import Op.
Require Import Mem.
Require Import Events.
Require Import Globalenvs.
+Require Import Smallstep.
Require Import Locations.
-Require Import Mach.
-Require Import Machabstr.
Require Import Linear.
Require Import Lineartyping.
+Require Import Mach.
+Require Import Machabstr.
+Require Import Bounds.
Require Import Conventions.
Require Import Stacking.
@@ -29,25 +32,28 @@ Require Import Stacking.
(** ``Good variable'' properties for frame accesses. *)
+Lemma typesize_typesize:
+ forall ty, AST.typesize ty = 4 * Locations.typesize ty.
+Proof.
+ destruct ty; auto.
+Qed.
+
Lemma get_slot_ok:
forall fr ty ofs,
- 0 <= ofs -> fr.(low) + ofs + 4 * typesize ty <= 0 ->
+ 24 <= ofs -> fr.(fr_low) + ofs + 4 * typesize ty <= 0 ->
exists v, get_slot fr ty ofs v.
Proof.
- intros. exists (load_contents (mem_type ty) fr.(contents) (fr.(low) + ofs)).
- constructor; auto.
+ intros. rewrite <- typesize_typesize in H0.
+ exists (fr.(fr_contents) ty (fr.(fr_low) + ofs)). constructor; auto.
Qed.
Lemma set_slot_ok:
forall fr ty ofs v,
- fr.(high) = 0 -> 0 <= ofs -> fr.(low) + ofs + 4 * typesize ty <= 0 ->
+ 24 <= ofs -> fr.(fr_low) + ofs + 4 * typesize ty <= 0 ->
exists fr', set_slot fr ty ofs v fr'.
Proof.
- intros.
- exists (mkblock fr.(low) fr.(high)
- (store_contents (mem_type ty) fr.(contents) (fr.(low) + ofs) v)
- (set_slot_undef_outside fr ty ofs v H H0 H1 fr.(undef_outside))).
- constructor; auto.
+ intros. rewrite <- typesize_typesize in H0.
+ econstructor. constructor; eauto.
Qed.
Lemma slot_gss:
@@ -55,10 +61,45 @@ Lemma slot_gss:
set_slot fr1 ty ofs v fr2 ->
get_slot fr2 ty ofs v.
Proof.
- intros. induction H.
- constructor.
- auto. simpl. auto.
- simpl. symmetry. apply load_store_contents_same.
+ intros. inv H. constructor; auto.
+ simpl. destruct (typ_eq ty ty); try congruence.
+ rewrite zeq_true. auto.
+Qed.
+
+Remark frame_update_gso:
+ forall fr ty ofs v ty' ofs',
+ ofs' + 4 * typesize ty' <= ofs \/ ofs + 4 * typesize ty <= ofs' ->
+ fr_contents (update ty ofs v fr) ty' ofs' = fr_contents fr ty' ofs'.
+Proof.
+ intros.
+ generalize (typesize_pos ty); intro.
+ generalize (typesize_pos ty'); intro.
+ simpl. rewrite zeq_false. 2: omega.
+ repeat rewrite <- typesize_typesize in H.
+ destruct (zle (ofs' + AST.typesize ty') ofs). auto.
+ destruct (zle (ofs + AST.typesize ty) ofs'). auto.
+ omegaContradiction.
+Qed.
+
+Remark frame_update_overlap:
+ forall fr ty ofs v ty' ofs',
+ ofs <> ofs' ->
+ ofs' + 4 * typesize ty' > ofs -> ofs + 4 * typesize ty > ofs' ->
+ fr_contents (update ty ofs v fr) ty' ofs' = Vundef.
+Proof.
+ intros. simpl. rewrite zeq_false; auto.
+ rewrite <- typesize_typesize in H0.
+ rewrite <- typesize_typesize in H1.
+ repeat rewrite zle_false; auto.
+Qed.
+
+Remark frame_update_mismatch:
+ forall fr ty ofs v ty',
+ ty <> ty' ->
+ fr_contents (update ty ofs v fr) ty' ofs = Vundef.
+Proof.
+ intros. simpl. rewrite zeq_true.
+ destruct (typ_eq ty ty'); congruence.
Qed.
Lemma slot_gso:
@@ -68,38 +109,36 @@ Lemma slot_gso:
ofs' + 4 * typesize ty' <= ofs \/ ofs + 4 * typesize ty <= ofs' ->
get_slot fr2 ty' ofs' v'.
Proof.
- intros. induction H; inversion H0.
- constructor.
- auto. simpl low. auto.
- simpl. rewrite H3. symmetry. apply load_store_contents_other.
- repeat (rewrite size_mem_type). omega.
+ intros. inv H. inv H0.
+ constructor; auto.
+ symmetry. simpl fr_low. apply frame_update_gso. omega.
Qed.
Lemma slot_gi:
forall f ofs ty,
- 0 <= ofs -> (init_frame f).(low) + ofs + 4 * typesize ty <= 0 ->
+ 24 <= ofs -> fr_low (init_frame f) + ofs + 4 * typesize ty <= 0 ->
get_slot (init_frame f) ty ofs Vundef.
Proof.
- intros. constructor.
- auto. auto.
- symmetry. apply load_contents_init.
+ intros. rewrite <- typesize_typesize in H0. constructor; auto.
Qed.
Section PRESERVATION.
Variable prog: Linear.program.
Variable tprog: Mach.program.
-Hypothesis TRANSF: transf_program prog = Some tprog.
+Hypothesis TRANSF: transf_program prog = OK tprog.
Let ge := Genv.globalenv prog.
Let tge := Genv.globalenv tprog.
+
Section FRAME_PROPERTIES.
+Variable stack: list Machabstr.stackframe.
Variable f: Linear.function.
Let b := function_bounds f.
Let fe := make_env b.
Variable tf: Mach.function.
-Hypothesis TRANSF_F: transf_function f = Some tf.
+Hypothesis TRANSF_F: transf_function f = OK tf.
Lemma unfold_transf_function:
tf = Mach.mkfunction
@@ -109,7 +148,7 @@ Lemma unfold_transf_function:
fe.(fe_size).
Proof.
generalize TRANSF_F. unfold transf_function.
- case (zlt (fn_stacksize f) 0). intros; discriminate.
+ case (zlt (Linear.fn_stacksize f) 0). intros; discriminate.
case (zlt (- Int.min_signed) (fe_size (make_env (function_bounds f)))).
intros; discriminate.
intros. unfold fe. unfold b. congruence.
@@ -118,7 +157,7 @@ Qed.
Lemma size_no_overflow: fe.(fe_size) <= -Int.min_signed.
Proof.
generalize TRANSF_F. unfold transf_function.
- case (zlt (fn_stacksize f) 0). intros; discriminate.
+ case (zlt (Linear.fn_stacksize f) 0). intros; discriminate.
case (zlt (- Int.min_signed) (fe_size (make_env (function_bounds f)))).
intros; discriminate.
intros. unfold fe, b. omega.
@@ -131,7 +170,7 @@ Definition index_valid (idx: frame_index) :=
match idx with
| FI_local x Tint => 0 <= x < b.(bound_int_local)
| FI_local x Tfloat => 0 <= x < b.(bound_float_local)
- | FI_arg x ty => 6 <= x /\ x + typesize ty <= b.(bound_outgoing)
+ | FI_arg x ty => 14 <= x /\ x + typesize ty <= b.(bound_outgoing)
| FI_saved_int x => 0 <= x < b.(bound_int_callee_save)
| FI_saved_float x => 0 <= x < b.(bound_float_callee_save)
end.
@@ -166,17 +205,12 @@ Proof.
Qed.
Ltac AddPosProps :=
- assert (bound_int_local b >= 0);
- [unfold b; apply bound_int_local_pos |
- assert (bound_float_local b >= 0);
- [unfold b; apply bound_float_local_pos |
- assert (bound_int_callee_save b >= 0);
- [unfold b; apply bound_int_callee_save_pos |
- assert (bound_float_callee_save b >= 0);
- [unfold b; apply bound_float_callee_save_pos |
- assert (bound_outgoing b >= 6);
- [unfold b; apply bound_outgoing_pos |
- generalize align_float_part; intro]]]]].
+ generalize (bound_int_local_pos b); intro;
+ generalize (bound_float_local_pos b); intro;
+ generalize (bound_int_callee_save_pos b); intro;
+ generalize (bound_float_callee_save_pos b); intro;
+ generalize (bound_outgoing_pos b); intro;
+ generalize align_float_part; intro.
Lemma size_pos: fe.(fe_size) >= 24.
Proof.
@@ -212,18 +246,18 @@ Qed.
Lemma index_local_valid:
forall ofs ty,
- slot_bounded f (Local ofs ty) ->
+ slot_within_bounds f b (Local ofs ty) ->
index_valid (FI_local ofs ty).
Proof.
- unfold slot_bounded, index_valid. auto.
+ unfold slot_within_bounds, index_valid. auto.
Qed.
Lemma index_arg_valid:
forall ofs ty,
- slot_bounded f (Outgoing ofs ty) ->
+ slot_within_bounds f b (Outgoing ofs ty) ->
index_valid (FI_arg ofs ty).
Proof.
- unfold slot_bounded, index_valid, b. auto.
+ unfold slot_within_bounds, index_valid. auto.
Qed.
Lemma index_saved_int_valid:
@@ -280,10 +314,8 @@ Lemma offset_of_index_no_overflow:
Proof.
intros.
generalize (offset_of_index_valid idx H). intros [A B].
-(* omega falls flat on its face... *)
apply Int.signed_repr.
- split. apply Zle_trans with 24. compute; intro; discriminate.
- auto.
+ split. apply Zle_trans with 24; auto. compute; intro; discriminate.
assert (offset_of_index fe idx < fe_size fe).
generalize (typesize_pos (type_of_index idx)); intro. omega.
apply Zlt_succ_le.
@@ -295,26 +327,30 @@ Qed.
instructions, in case the offset is computed with [offset_of_index]. *)
Lemma exec_Mgetstack':
- forall sp parent idx ty c rs fr dst m v,
+ forall sp idx ty c rs fr dst m v,
index_valid idx ->
get_slot fr ty (offset_of_index fe idx) v ->
- Machabstr.exec_instrs tge tf sp parent
- (Mgetstack (Int.repr (offset_of_index fe idx)) ty dst :: c) rs fr m
- E0 c (rs#dst <- v) fr m.
+ step tge
+ (State stack tf sp
+ (Mgetstack (Int.repr (offset_of_index fe idx)) ty dst :: c)
+ rs fr m)
+ E0 (State stack tf sp c (rs#dst <- v) fr m).
Proof.
- intros. apply Machabstr.exec_one. apply Machabstr.exec_Mgetstack.
+ intros. apply exec_Mgetstack.
rewrite offset_of_index_no_overflow. auto. auto.
Qed.
Lemma exec_Msetstack':
- forall sp parent idx ty c rs fr src m fr',
+ forall sp idx ty c rs fr src m fr',
index_valid idx ->
set_slot fr ty (offset_of_index fe idx) (rs src) fr' ->
- Machabstr.exec_instrs tge tf sp parent
- (Msetstack src (Int.repr (offset_of_index fe idx)) ty :: c) rs fr m
- E0 c rs fr' m.
+ step tge
+ (State stack tf sp
+ (Msetstack src (Int.repr (offset_of_index fe idx)) ty :: c)
+ rs fr m)
+ E0 (State stack tf sp c rs fr' m).
Proof.
- intros. apply Machabstr.exec_one. apply Machabstr.exec_Msetstack.
+ intros. apply exec_Msetstack.
rewrite offset_of_index_no_overflow. auto. auto.
Qed.
@@ -323,44 +359,42 @@ Qed.
function. *)
Definition index_val (idx: frame_index) (fr: frame) :=
- load_contents (mem_type (type_of_index idx))
- fr.(contents)
- (fr.(low) + offset_of_index fe idx).
+ fr.(fr_contents) (type_of_index idx) (fr.(fr_low) + offset_of_index fe idx).
Lemma get_slot_index:
forall fr idx ty v,
index_valid idx ->
- fr.(low) = - fe.(fe_size) ->
+ fr.(fr_low) = -fe.(fe_size) ->
ty = type_of_index idx ->
v = index_val idx fr ->
get_slot fr ty (offset_of_index fe idx) v.
Proof.
intros. subst v; subst ty.
generalize (offset_of_index_valid idx H); intros [A B].
- unfold index_val. apply get_slot_intro. omega.
- rewrite H0. omega. auto.
+ rewrite <- typesize_typesize in B.
+ unfold index_val. apply get_slot_intro; auto.
+ rewrite H0. omega.
Qed.
Lemma set_slot_index:
forall fr idx v,
index_valid idx ->
- fr.(high) = 0 ->
- fr.(low) = - fe.(fe_size) ->
+ fr.(fr_low) = -fe.(fe_size) ->
exists fr', set_slot fr (type_of_index idx) (offset_of_index fe idx) v fr'.
Proof.
intros.
generalize (offset_of_index_valid idx H); intros [A B].
- apply set_slot_ok. auto. omega. rewrite H1; omega.
+ apply set_slot_ok; auto. rewrite H0. omega.
Qed.
(** Alternate ``good variable'' properties for [get_slot] and [set_slot]. *)
+
Lemma slot_iss:
forall fr idx v fr',
set_slot fr (type_of_index idx) (offset_of_index fe idx) v fr' ->
index_val idx fr' = v.
Proof.
- intros. inversion H. subst ofs ty.
- unfold index_val; simpl. apply load_store_contents_same.
+ intros. exploit slot_gss; eauto. intro. inv H0. auto.
Qed.
Lemma slot_iso:
@@ -371,19 +405,20 @@ Lemma slot_iso:
index_val idx' fr' = index_val idx' fr.
Proof.
intros. generalize (offset_of_index_disj idx idx' H1 H2 H0). intro.
- unfold index_val. inversion H. subst ofs ty. simpl.
- apply load_store_contents_other.
- repeat rewrite size_mem_type. omega.
+ inv H. unfold index_val. simpl fr_low. apply frame_update_gso.
+ omega.
Qed.
(** * Agreement between location sets and Mach environments *)
-(** The following [agree] predicate expresses semantic agreement between
- a location set on the Linear side and, on the Mach side,
- a register set, plus the current and parent frames, plus the register
- set [rs0] at function entry. *)
+(** The following [agree] predicate expresses semantic agreement between:
+- on the Linear side, the current location set [ls] and the location
+ set at function entry [ls0];
+- on the Mach side, a register set [rs] plus the current and parent frames
+ [fr] and [parent].
+*)
-Record agree (ls: locset) (rs: regset) (fr parent: frame) (rs0: regset) : Prop :=
+Record agree (ls: locset) (rs: regset) (fr parent: frame) (ls0: locset) : Prop :=
mk_agree {
(** Machine registers have the same values on the Linear and Mach sides. *)
agree_reg:
@@ -393,25 +428,22 @@ Record agree (ls: locset) (rs: regset) (fr parent: frame) (rs0: regset) : Prop :
have the same values they had at function entry. In other terms,
these registers are never assigned. *)
agree_unused_reg:
- forall r, ~(mreg_bounded f r) -> rs r = rs0 r;
+ forall r, ~(mreg_within_bounds b r) -> rs r = ls0 (R r);
- (** The bounds of the current frame are [[- fe.(fe_size), 0]]. *)
- agree_high:
- fr.(high) = 0;
+ (** The low bound of the current frame is [- fe.(fe_size)]. *)
agree_size:
- fr.(low) = - fe.(fe_size);
+ fr.(fr_low) = -fe.(fe_size);
(** Local and outgoing stack slots (on the Linear side) have
the same values as the one loaded from the current Mach frame
at the corresponding offsets. *)
-
agree_locals:
forall ofs ty,
- slot_bounded f (Local ofs ty) ->
+ slot_within_bounds f b (Local ofs ty) ->
ls (S (Local ofs ty)) = index_val (FI_local ofs ty) fr;
agree_outgoing:
forall ofs ty,
- slot_bounded f (Outgoing ofs ty) ->
+ slot_within_bounds f b (Outgoing ofs ty) ->
ls (S (Outgoing ofs ty)) = index_val (FI_arg ofs ty) fr;
(** Incoming stack slots (on the Linear side) have
@@ -419,7 +451,7 @@ Record agree (ls: locset) (rs: regset) (fr parent: frame) (rs0: regset) : Prop :
at the corresponding offsets. *)
agree_incoming:
forall ofs ty,
- slot_bounded f (Incoming ofs ty) ->
+ slot_within_bounds f b (Incoming ofs ty) ->
get_slot parent ty (Int.signed (Int.repr (4 * ofs))) (ls (S (Incoming ofs ty)));
(** The areas of the frame reserved for saving used callee-save
@@ -429,35 +461,33 @@ Record agree (ls: locset) (rs: regset) (fr parent: frame) (rs0: regset) : Prop :
forall r,
In r int_callee_save_regs ->
index_int_callee_save r < b.(bound_int_callee_save) ->
- index_val (FI_saved_int (index_int_callee_save r)) fr = rs0 r;
+ index_val (FI_saved_int (index_int_callee_save r)) fr = ls0 (R r);
agree_saved_float:
forall r,
In r float_callee_save_regs ->
index_float_callee_save r < b.(bound_float_callee_save) ->
- index_val (FI_saved_float (index_float_callee_save r)) fr = rs0 r
+ index_val (FI_saved_float (index_float_callee_save r)) fr = ls0 (R r)
}.
-Hint Resolve agree_reg agree_unused_reg agree_size agree_high
+Hint Resolve agree_reg agree_unused_reg agree_size
agree_locals agree_outgoing agree_incoming
agree_saved_int agree_saved_float: stacking.
(** Values of registers and register lists. *)
Lemma agree_eval_reg:
- forall ls rs fr parent rs0 r,
- agree ls rs fr parent rs0 -> rs r = ls (R r).
+ forall ls rs fr parent ls0 r,
+ agree ls rs fr parent ls0 -> rs r = ls (R r).
Proof.
intros. symmetry. eauto with stacking.
Qed.
Lemma agree_eval_regs:
- forall ls rs fr parent rs0 rl,
- agree ls rs fr parent rs0 -> rs##rl = LTL.reglist rl ls.
+ forall ls rs fr parent ls0 rl,
+ agree ls rs fr parent ls0 -> rs##rl = reglist ls rl.
Proof.
induction rl; simpl; intros.
- auto. apply (f_equal2 (@cons val)).
- eapply agree_eval_reg; eauto.
- auto.
+ auto. f_equal. eapply agree_eval_reg; eauto. auto.
Qed.
Hint Resolve agree_eval_reg agree_eval_regs: stacking.
@@ -466,10 +496,10 @@ Hint Resolve agree_eval_reg agree_eval_regs: stacking.
of machine registers, of local slots, of outgoing slots. *)
Lemma agree_set_reg:
- forall ls rs fr parent rs0 r v,
- agree ls rs fr parent rs0 ->
- mreg_bounded f r ->
- agree (Locmap.set (R r) v ls) (Regmap.set r v rs) fr parent rs0.
+ forall ls rs fr parent ls0 r v,
+ agree ls rs fr parent ls0 ->
+ mreg_within_bounds b r ->
+ agree (Locmap.set (R r) v ls) (Regmap.set r v rs) fr parent ls0.
Proof.
intros. constructor; eauto with stacking.
intros. case (mreg_eq r r0); intro.
@@ -484,25 +514,22 @@ Proof.
Qed.
Lemma agree_set_local:
- forall ls rs fr parent rs0 v ofs ty,
- agree ls rs fr parent rs0 ->
- slot_bounded f (Local ofs ty) ->
+ forall ls rs fr parent ls0 v ofs ty,
+ agree ls rs fr parent ls0 ->
+ slot_within_bounds f b (Local ofs ty) ->
exists fr',
set_slot fr ty (offset_of_index fe (FI_local ofs ty)) v fr' /\
- agree (Locmap.set (S (Local ofs ty)) v ls) rs fr' parent rs0.
+ agree (Locmap.set (S (Local ofs ty)) v ls) rs fr' parent ls0.
Proof.
intros.
generalize (set_slot_index fr _ v (index_local_valid _ _ H0)
- (agree_high _ _ _ _ _ H)
(agree_size _ _ _ _ _ H)).
intros [fr' SET].
exists fr'. split. auto. constructor; eauto with stacking.
(* agree_reg *)
intros. rewrite Locmap.gso. eauto with stacking. red; auto.
- (* agree_high *)
- inversion SET. simpl high. eauto with stacking.
(* agree_size *)
- inversion SET. simpl low. eauto with stacking.
+ inversion SET. rewrite H3; simpl fr_low. eauto with stacking.
(* agree_local *)
intros. case (slot_eq (Local ofs ty) (Local ofs0 ty0)); intro.
rewrite <- e. rewrite Locmap.gss.
@@ -517,7 +544,7 @@ Proof.
(* agree_outgoing *)
intros. rewrite Locmap.gso. transitivity (index_val (FI_arg ofs0 ty0) fr).
eauto with stacking. symmetry. eapply slot_iso; eauto.
- red; auto. red; auto.
+ red; auto. red; auto.
(* agree_incoming *)
intros. rewrite Locmap.gso. eauto with stacking. red. auto.
(* agree_saved_int *)
@@ -529,30 +556,27 @@ Proof.
Qed.
Lemma agree_set_outgoing:
- forall ls rs fr parent rs0 v ofs ty,
- agree ls rs fr parent rs0 ->
- slot_bounded f (Outgoing ofs ty) ->
+ forall ls rs fr parent ls0 v ofs ty,
+ agree ls rs fr parent ls0 ->
+ slot_within_bounds f b (Outgoing ofs ty) ->
exists fr',
set_slot fr ty (offset_of_index fe (FI_arg ofs ty)) v fr' /\
- agree (Locmap.set (S (Outgoing ofs ty)) v ls) rs fr' parent rs0.
+ agree (Locmap.set (S (Outgoing ofs ty)) v ls) rs fr' parent ls0.
Proof.
intros.
generalize (set_slot_index fr _ v (index_arg_valid _ _ H0)
- (agree_high _ _ _ _ _ H)
(agree_size _ _ _ _ _ H)).
intros [fr' SET].
exists fr'. split. exact SET. constructor; eauto with stacking.
(* agree_reg *)
intros. rewrite Locmap.gso. eauto with stacking. red; auto.
- (* agree_high *)
- inversion SET. simpl high. eauto with stacking.
(* agree_size *)
- inversion SET. simpl low. eauto with stacking.
+ inversion SET. subst fr'; simpl fr_low. eauto with stacking.
(* agree_local *)
intros. rewrite Locmap.gso.
transitivity (index_val (FI_local ofs0 ty0) fr).
eauto with stacking. symmetry. eapply slot_iso; eauto.
- red; auto. red; auto.
+ red; auto. red; auto.
(* agree_outgoing *)
intros. unfold Locmap.set.
case (Loc.eq (S (Outgoing ofs ty)) (S (Outgoing ofs0 ty0))); intro.
@@ -562,18 +586,12 @@ Proof.
congruence. congruence.
(* overlapping locations *)
caseEq (Loc.overlap (S (Outgoing ofs ty)) (S (Outgoing ofs0 ty0))); intros.
- inversion SET. subst ofs1 ty1.
- unfold index_val, type_of_index, offset_of_index.
- set (ofs4 := 4 * ofs). set (ofs04 := 4 * ofs0). simpl.
- unfold ofs4, ofs04. symmetry.
- case (zeq ofs ofs0); intro.
- subst ofs0. apply load_store_contents_mismatch.
+ inv SET. unfold index_val, type_of_index, offset_of_index.
+ destruct (zeq ofs ofs0).
+ subst ofs0. symmetry. apply frame_update_mismatch.
destruct ty; destruct ty0; simpl; congruence.
- generalize (Loc.overlap_not_diff _ _ H2). intro. simpl in H4.
- apply load_store_contents_overlap.
- omega.
- rewrite size_mem_type. omega.
- rewrite size_mem_type. omega.
+ generalize (Loc.overlap_not_diff _ _ H2). intro. simpl in H5.
+ simpl fr_low. symmetry. apply frame_update_overlap. omega. omega. omega.
(* different locations *)
transitivity (index_val (FI_arg ofs0 ty0) fr).
eauto with stacking.
@@ -588,17 +606,17 @@ Proof.
intros. rewrite <- (agree_saved_float _ _ _ _ _ H r H1 H2).
eapply slot_iso; eauto with stacking. red; auto.
Qed.
-
+(*
Lemma agree_return_regs:
- forall ls rs fr parent rs0 ls' rs',
- agree ls rs fr parent rs0 ->
+ forall ls rs fr parent ls0 ls' rs',
+ agree ls rs fr parent ls0 ->
(forall r,
In (R r) temporaries \/ In (R r) destroyed_at_call ->
rs' r = ls' (R r)) ->
(forall r,
In r int_callee_save_regs \/ In r float_callee_save_regs ->
rs' r = rs r) ->
- agree (LTL.return_regs ls ls') rs' fr parent rs0.
+ agree (LTL.return_regs ls ls') rs' fr parent ls0.
Proof.
intros. constructor; unfold LTL.return_regs; eauto with stacking.
(* agree_reg *)
@@ -610,12 +628,117 @@ Proof.
generalize (register_classification r); tauto.
(* agree_unused_reg *)
intros. rewrite H1. eauto with stacking.
- generalize H2; unfold mreg_bounded; case (mreg_type r); intro.
+ generalize H2; unfold mreg_within_bounds; case (mreg_type r); intro.
left. apply index_int_callee_save_pos2.
- generalize (bound_int_callee_save_pos f); intro. omega.
+ generalize (bound_int_callee_save_pos b); intro. omega.
right. apply index_float_callee_save_pos2.
- generalize (bound_float_callee_save_pos f); intro. omega.
+ generalize (bound_float_callee_save_pos b); intro. omega.
Qed.
+*)
+
+Lemma agree_return_regs:
+ forall ls rs fr parent ls0 rs',
+ agree ls rs fr parent ls0 ->
+ (forall r,
+ ~In r int_callee_save_regs -> ~In r float_callee_save_regs ->
+ rs' r = rs r) ->
+ (forall r,
+ In r int_callee_save_regs \/ In r float_callee_save_regs ->
+ rs' r = ls0 (R r)) ->
+ (forall r, LTL.return_regs ls0 ls (R r) = rs' r).
+Proof.
+ intros; unfold LTL.return_regs.
+ case (In_dec Loc.eq (R r) temporaries); intro.
+ rewrite H0. eapply agree_reg; eauto.
+ apply int_callee_save_not_destroyed; auto.
+ apply float_callee_save_not_destroyed; auto.
+ case (In_dec Loc.eq (R r) destroyed_at_call); intro.
+ rewrite H0. eapply agree_reg; eauto.
+ apply int_callee_save_not_destroyed; auto.
+ apply float_callee_save_not_destroyed; auto.
+ symmetry; apply H1.
+ generalize (register_classification r); tauto.
+Qed.
+
+(** Agreement over callee-save registers and stack locations *)
+
+Definition agree_callee_save (ls1 ls2: locset) : Prop :=
+ forall l,
+ match l with
+ | R r => In r int_callee_save_regs \/ In r float_callee_save_regs
+ | S s => True
+ end ->
+ ls2 l = ls1 l.
+
+Remark mreg_not_within_bounds:
+ forall r,
+ ~mreg_within_bounds b r -> In r int_callee_save_regs \/ In r float_callee_save_regs.
+Proof.
+ intro r; unfold mreg_within_bounds.
+ destruct (mreg_type r); intro.
+ left. apply index_int_callee_save_pos2.
+ generalize (bound_int_callee_save_pos b). omega.
+ right. apply index_float_callee_save_pos2.
+ generalize (bound_float_callee_save_pos b). omega.
+Qed.
+
+Lemma agree_callee_save_agree:
+ forall ls rs fr parent ls1 ls2,
+ agree ls rs fr parent ls1 ->
+ agree_callee_save ls1 ls2 ->
+ agree ls rs fr parent ls2.
+Proof.
+ intros. inv H. constructor; auto.
+ intros. rewrite agree_unused_reg0; auto.
+ symmetry. apply H0. apply mreg_not_within_bounds; auto.
+ intros. rewrite (H0 (R r)); auto.
+ intros. rewrite (H0 (R r)); auto.
+Qed.
+
+Lemma agree_callee_save_return_regs:
+ forall ls1 ls2,
+ agree_callee_save (LTL.return_regs ls1 ls2) ls1.
+Proof.
+ intros; red; intros.
+ unfold LTL.return_regs. destruct l; auto.
+ generalize (int_callee_save_not_destroyed m); intro.
+ generalize (float_callee_save_not_destroyed m); intro.
+ destruct (In_dec Loc.eq (R m) temporaries). tauto.
+ destruct (In_dec Loc.eq (R m) destroyed_at_call). tauto.
+ auto.
+Qed.
+
+Lemma agree_callee_save_set_result:
+ forall ls1 ls2 v sg,
+ agree_callee_save ls1 ls2 ->
+ agree_callee_save (Locmap.set (R (Conventions.loc_result sg)) v ls1) ls2.
+Proof.
+ intros; red; intros. rewrite H; auto.
+ symmetry; apply Locmap.gso. destruct l; simpl; auto.
+ red; intro. subst m. elim (loc_result_not_callee_save _ H0).
+Qed.
+
+(** A variant of [agree] used for return frames. *)
+
+Definition agree_frame (ls: locset) (fr parent: frame) (ls0: locset) : Prop :=
+ exists rs, agree ls rs fr parent ls0.
+
+Lemma agree_frame_agree:
+ forall ls1 ls2 rs fr parent ls0,
+ agree_frame ls1 fr parent ls0 ->
+ agree_callee_save ls2 ls1 ->
+ (forall r, rs r = ls2 (R r)) ->
+ agree ls2 rs fr parent ls0.
+Proof.
+ intros. destruct H as [rs' AG]. inv AG.
+ constructor; auto.
+ intros. rewrite <- agree_unused_reg0; auto.
+ rewrite <- agree_reg0. rewrite H1. symmetry; apply H0.
+ apply mreg_not_within_bounds; auto.
+ intros. rewrite <- H0; auto.
+ intros. rewrite <- H0; auto.
+ intros. rewrite <- H0; auto.
+Qed.
(** * Correctness of saving and restoring of callee-save registers *)
@@ -624,87 +747,100 @@ Qed.
the register save areas of the current frame do contain the
values of the callee-save registers used by the function. *)
-Lemma save_int_callee_save_correct_rec:
- forall l k sp parent rs fr m,
- incl l int_callee_save_regs ->
+Section SAVE_CALLEE_SAVE.
+
+Variable bound: frame_env -> Z.
+Variable number: mreg -> Z.
+Variable mkindex: Z -> frame_index.
+Variable ty: typ.
+Variable sp: val.
+Variable csregs: list mreg.
+Hypothesis number_inj:
+ forall r1 r2, In r1 csregs -> In r2 csregs -> r1 <> r2 -> number r1 <> number r2.
+Hypothesis mkindex_valid:
+ forall r, In r csregs -> number r < bound fe -> index_valid (mkindex (number r)).
+Hypothesis mkindex_typ:
+ forall z, type_of_index (mkindex z) = ty.
+Hypothesis mkindex_inj:
+ forall z1 z2, z1 <> z2 -> mkindex z1 <> mkindex z2.
+Hypothesis mkindex_diff:
+ forall r idx,
+ idx <> mkindex (number r) -> index_diff (mkindex (number r)) idx.
+
+Lemma save_callee_save_regs_correct:
+ forall l k rs fr m,
+ incl l csregs ->
list_norepet l ->
- fr.(high) = 0 ->
- fr.(low) = -fe.(fe_size) ->
+ fr.(fr_low) = -fe.(fe_size) ->
exists fr',
- Machabstr.exec_instrs tge tf sp parent
- (List.fold_right (save_int_callee_save fe) k l) rs fr m
- E0 k rs fr' m
- /\ fr'.(high) = 0
- /\ fr'.(low) = -fe.(fe_size)
+ star step tge
+ (State stack tf sp
+ (save_callee_save_regs bound number mkindex ty fe l k) rs fr m)
+ E0 (State stack tf sp k rs fr' m)
+ /\ fr'.(fr_low) = - fe.(fe_size)
/\ (forall r,
- In r l -> index_int_callee_save r < bound_int_callee_save b ->
- index_val (FI_saved_int (index_int_callee_save r)) fr' = rs r)
+ In r l -> number r < bound fe ->
+ index_val (mkindex (number r)) fr' = rs r)
/\ (forall idx,
index_valid idx ->
(forall r,
- In r l -> index_int_callee_save r < bound_int_callee_save b ->
- idx <> FI_saved_int (index_int_callee_save r)) ->
+ In r l -> number r < bound fe -> idx <> mkindex (number r)) ->
index_val idx fr' = index_val idx fr).
Proof.
- induction l.
+ induction l; intros; simpl save_callee_save_regs.
(* base case *)
- intros. simpl fold_right. exists fr.
- split. apply Machabstr.exec_refl. split. auto. split. auto.
- split. intros. elim H3. auto.
+ exists fr. split. apply star_refl. split. auto.
+ split. intros. elim H2. auto.
(* inductive case *)
- intros. simpl fold_right.
- set (k1 := fold_right (save_int_callee_save fe) k l) in *.
- assert (R1: incl l int_callee_save_regs). eauto with coqlib.
+ set (k1 := save_callee_save_regs bound number mkindex ty fe l k).
+ assert (R1: incl l csregs). eauto with coqlib.
assert (R2: list_norepet l). inversion H0; auto.
- unfold save_int_callee_save.
- case (zlt (index_int_callee_save a) (fe_num_int_callee_save fe));
- intro;
- unfold fe_num_int_callee_save, fe, make_env in z.
+ unfold save_callee_save_reg.
+ destruct (zlt (number a) (bound fe)).
(* a store takes place *)
- assert (IDX: index_valid (FI_saved_int (index_int_callee_save a))).
- apply index_saved_int_valid. eauto with coqlib. auto.
- generalize (set_slot_index _ _ (rs a) IDX H1 H2).
+ assert (VALID: index_valid (mkindex (number a))).
+ apply mkindex_valid. auto with coqlib. auto.
+ exploit set_slot_index; eauto.
intros [fr1 SET].
- assert (R3: high fr1 = 0). inversion SET. simpl high. auto.
- assert (R4: low fr1 = -fe_size fe). inversion SET. simpl low. auto.
- generalize (IHl k sp parent rs fr1 m R1 R2 R3 R4).
- intros [fr' [A [B [C [D E]]]]].
- exists fr'.
- split. eapply Machabstr.exec_trans. apply exec_Msetstack'; eauto with stacking.
+ exploit (IHl k rs fr1 m); auto. inv SET; auto.
+ fold k1. intros [fr' [A [B [C D]]]].
+ exists fr'.
+ split. eapply star_left.
+ apply exec_Msetstack'; eauto with stacking. rewrite <- (mkindex_typ (number a)). eauto.
eexact A. traceEq.
- split. auto.
- split. auto.
- split. intros. elim H3; intros. subst r.
- rewrite E. eapply slot_iss; eauto. auto.
- intros. decEq. apply index_int_callee_save_inj; auto with coqlib.
+ split. auto.
+ split. intros. elim H2; intros. subst r.
+ rewrite D. eapply slot_iss; eauto.
+ apply mkindex_valid; auto.
+ intros. apply mkindex_inj. apply number_inj; auto with coqlib.
inversion H0. red; intro; subst r; contradiction.
- apply D; auto.
+ apply C; auto.
intros. transitivity (index_val idx fr1).
- apply E; auto.
- intros. apply H4; eauto with coqlib.
- eapply slot_iso; eauto.
- destruct idx; simpl; auto.
- generalize (H4 a (in_eq _ _) z). congruence.
- (* no store takes place *)
- generalize (IHl k sp parent rs fr m R1 R2 H1 H2).
- intros [fr' [A [B [C [D E]]]]].
- exists fr'. split. exact A. split. exact B. split. exact C.
- split. intros. elim H3; intros. subst r. omegaContradiction.
apply D; auto.
- intros. apply E; auto.
- intros. apply H4; auto with coqlib.
-Qed.
+ intros. apply H3; eauto with coqlib.
+ eapply slot_iso; eauto.
+ apply mkindex_diff. apply H3. auto with coqlib.
+ auto.
+ (* no store takes place *)
+ exploit (IHl k rs fr m); auto. intros [fr' [A [B [C D]]]].
+ exists fr'. split. exact A. split. exact B.
+ split. intros. elim H2; intros. subst r. omegaContradiction.
+ apply C; auto.
+ intros. apply D; auto.
+ intros. apply H3; auto with coqlib.
+Qed.
-Lemma save_int_callee_save_correct:
- forall k sp parent rs fr m,
- fr.(high) = 0 ->
- fr.(low) = -fe.(fe_size) ->
+End SAVE_CALLEE_SAVE.
+
+Lemma save_callee_save_int_correct:
+ forall k sp rs fr m,
+ fr.(fr_low) = - fe.(fe_size) ->
exists fr',
- Machabstr.exec_instrs tge tf sp parent
- (List.fold_right (save_int_callee_save fe) k int_callee_save_regs) rs fr m
- E0 k rs fr' m
- /\ fr'.(high) = 0
- /\ fr'.(low) = -fe.(fe_size)
+ star step tge
+ (State stack tf sp
+ (save_callee_save_int fe k) rs fr m)
+ E0 (State stack tf sp k rs fr' m)
+ /\ fr'.(fr_low) = - fe.(fe_size)
/\ (forall r,
In r int_callee_save_regs ->
index_int_callee_save r < bound_int_callee_save b ->
@@ -714,98 +850,30 @@ Lemma save_int_callee_save_correct:
match idx with FI_saved_int _ => False | _ => True end ->
index_val idx fr' = index_val idx fr).
Proof.
- intros.
- generalize (save_int_callee_save_correct_rec
- int_callee_save_regs k sp parent rs fr m
- (incl_refl _) int_callee_save_norepet H H0).
- intros [fr' [A [B [C [D E]]]]].
- exists fr'.
- split. assumption. split. assumption. split. assumption.
- split. apply D. intros. apply E. auto.
- intros. red; intros; subst idx. contradiction.
+ intros.
+ exploit (save_callee_save_regs_correct fe_num_int_callee_save index_int_callee_save FI_saved_int
+ Tint sp int_callee_save_regs).
+ exact index_int_callee_save_inj.
+ intros. red. split; auto. generalize (index_int_callee_save_pos r H0). omega.
+ auto.
+ intros; congruence.
+ intros until idx. destruct idx; simpl; auto. congruence.
+ apply incl_refl.
+ apply int_callee_save_norepet. eauto.
+ intros [fr' [A [B [C D]]]].
+ exists fr'; intuition. unfold save_callee_save_int; eauto.
+ apply D. auto. intros; subst idx. auto.
Qed.
-Lemma save_float_callee_save_correct_rec:
- forall l k sp parent rs fr m,
- incl l float_callee_save_regs ->
- list_norepet l ->
- fr.(high) = 0 ->
- fr.(low) = -fe.(fe_size) ->
- exists fr',
- Machabstr.exec_instrs tge tf sp parent
- (List.fold_right (save_float_callee_save fe) k l) rs fr m
- E0 k rs fr' m
- /\ fr'.(high) = 0
- /\ fr'.(low) = -fe.(fe_size)
- /\ (forall r,
- In r l -> index_float_callee_save r < bound_float_callee_save b ->
- index_val (FI_saved_float (index_float_callee_save r)) fr' = rs r)
- /\ (forall idx,
- index_valid idx ->
- (forall r,
- In r l -> index_float_callee_save r < bound_float_callee_save b ->
- idx <> FI_saved_float (index_float_callee_save r)) ->
- index_val idx fr' = index_val idx fr).
-Proof.
- induction l.
- (* base case *)
- intros. simpl fold_right. exists fr.
- split. apply Machabstr.exec_refl. split. auto. split. auto.
- split. intros. elim H3. auto.
- (* inductive case *)
- intros. simpl fold_right.
- set (k1 := fold_right (save_float_callee_save fe) k l) in *.
- assert (R1: incl l float_callee_save_regs). eauto with coqlib.
- assert (R2: list_norepet l). inversion H0; auto.
- unfold save_float_callee_save.
- case (zlt (index_float_callee_save a) (fe_num_float_callee_save fe));
- intro;
- unfold fe_num_float_callee_save, fe, make_env in z.
- (* a store takes place *)
- assert (IDX: index_valid (FI_saved_float (index_float_callee_save a))).
- apply index_saved_float_valid. eauto with coqlib. auto.
- generalize (set_slot_index _ _ (rs a) IDX H1 H2).
- intros [fr1 SET].
- assert (R3: high fr1 = 0). inversion SET. simpl high. auto.
- assert (R4: low fr1 = -fe_size fe). inversion SET. simpl low. auto.
- generalize (IHl k sp parent rs fr1 m R1 R2 R3 R4).
- intros [fr' [A [B [C [D E]]]]].
- exists fr'.
- split. eapply Machabstr.exec_trans. apply exec_Msetstack'; eauto with stacking.
- eexact A. traceEq.
- split. auto.
- split. auto.
- split. intros. elim H3; intros. subst r.
- rewrite E. eapply slot_iss; eauto. auto.
- intros. decEq. apply index_float_callee_save_inj; auto with coqlib.
- inversion H0. red; intro; subst r; contradiction.
- apply D; auto.
- intros. transitivity (index_val idx fr1).
- apply E; auto.
- intros. apply H4; eauto with coqlib.
- eapply slot_iso; eauto.
- destruct idx; simpl; auto.
- generalize (H4 a (in_eq _ _) z). congruence.
- (* no store takes place *)
- generalize (IHl k sp parent rs fr m R1 R2 H1 H2).
- intros [fr' [A [B [C [D E]]]]].
- exists fr'. split. exact A. split. exact B. split. exact C.
- split. intros. elim H3; intros. subst r. omegaContradiction.
- apply D; auto.
- intros. apply E; auto.
- intros. apply H4; auto with coqlib.
-Qed.
-
-Lemma save_float_callee_save_correct:
- forall k sp parent rs fr m,
- fr.(high) = 0 ->
- fr.(low) = -fe.(fe_size) ->
+Lemma save_callee_save_float_correct:
+ forall k sp rs fr m,
+ fr.(fr_low) = - fe.(fe_size) ->
exists fr',
- Machabstr.exec_instrs tge tf sp parent
- (List.fold_right (save_float_callee_save fe) k float_callee_save_regs) rs fr m
- E0 k rs fr' m
- /\ fr'.(high) = 0
- /\ fr'.(low) = -fe.(fe_size)
+ star step tge
+ (State stack tf sp
+ (save_callee_save_float fe k) rs fr m)
+ E0 (State stack tf sp k rs fr' m)
+ /\ fr'.(fr_low) = - fe.(fe_size)
/\ (forall r,
In r float_callee_save_regs ->
index_float_callee_save r < bound_float_callee_save b ->
@@ -815,63 +883,59 @@ Lemma save_float_callee_save_correct:
match idx with FI_saved_float _ => False | _ => True end ->
index_val idx fr' = index_val idx fr).
Proof.
- intros.
- generalize (save_float_callee_save_correct_rec
- float_callee_save_regs k sp parent rs fr m
- (incl_refl _) float_callee_save_norepet H H0).
- intros [fr' [A [B [C [D E]]]]].
- exists fr'. split. assumption. split. assumption. split. assumption.
- split. apply D. intros. apply E. auto.
- intros. red; intros; subst idx. contradiction.
-Qed.
-
-Lemma index_val_init_frame:
- forall idx,
- index_valid idx ->
- index_val idx (init_frame tf) = Vundef.
-Proof.
- intros. unfold index_val, init_frame. simpl contents.
- apply load_contents_init.
+ intros.
+ exploit (save_callee_save_regs_correct fe_num_float_callee_save index_float_callee_save FI_saved_float
+ Tfloat sp float_callee_save_regs).
+ exact index_float_callee_save_inj.
+ intros. red. split; auto. generalize (index_float_callee_save_pos r H0). omega.
+ auto.
+ intros; congruence.
+ intros until idx. destruct idx; simpl; auto. congruence.
+ apply incl_refl.
+ apply float_callee_save_norepet. eauto.
+ intros [fr' [A [B [C D]]]].
+ exists fr'; intuition. unfold save_callee_save_float; eauto.
+ apply D. auto. intros; subst idx. auto.
Qed.
Lemma save_callee_save_correct:
- forall sp parent k rs fr m ls,
+ forall sp k rs fr m ls,
(forall r, rs r = ls (R r)) ->
(forall ofs ty,
- 6 <= ofs ->
- ofs + typesize ty <= size_arguments f.(fn_sig) ->
- get_slot parent ty (Int.signed (Int.repr (4 * ofs))) (ls (S (Outgoing ofs ty)))) ->
- high fr = 0 ->
- low fr = -fe.(fe_size) ->
+ 14 <= ofs ->
+ ofs + typesize ty <= size_arguments f.(Linear.fn_sig) ->
+ get_slot (parent_frame stack) ty (Int.signed (Int.repr (4 * ofs))) (ls (S (Outgoing ofs ty)))) ->
+ fr.(fr_low) = - fe.(fe_size) ->
(forall idx, index_valid idx -> index_val idx fr = Vundef) ->
exists fr',
- Machabstr.exec_instrs tge tf sp parent
- (save_callee_save fe k) rs fr m
- E0 k rs fr' m
- /\ agree (LTL.call_regs ls) rs fr' parent rs.
+ star step tge
+ (State stack tf sp (save_callee_save fe k) rs fr m)
+ E0 (State stack tf sp k rs fr' m)
+ /\ agree (LTL.call_regs ls) rs fr' (parent_frame stack) ls.
Proof.
intros. unfold save_callee_save.
- generalize (save_int_callee_save_correct
- (fold_right (save_float_callee_save fe) k float_callee_save_regs)
- sp parent rs fr m H1 H2).
- intros [fr1 [A1 [B1 [C1 [D1 E1]]]]].
- generalize (save_float_callee_save_correct k sp parent rs fr1 m B1 C1).
- intros [fr2 [A2 [B2 [C2 [D2 E2]]]]].
+ exploit save_callee_save_int_correct; eauto.
+ intros [fr1 [A1 [B1 [C1 D1]]]].
+ exploit save_callee_save_float_correct. eexact B1.
+ intros [fr2 [A2 [B2 [C2 D2]]]].
exists fr2.
- split. eapply Machabstr.exec_trans. eexact A1. eexact A2. traceEq.
+ split. eapply star_trans. eexact A1. eexact A2. traceEq.
constructor; unfold LTL.call_regs; auto.
(* agree_local *)
- intros. rewrite E2; auto with stacking.
- rewrite E1; auto with stacking.
+ intros. rewrite D2; auto with stacking.
+ rewrite D1; auto with stacking.
symmetry. auto with stacking.
(* agree_outgoing *)
- intros. rewrite E2; auto with stacking.
- rewrite E1; auto with stacking.
+ intros. rewrite D2; auto with stacking.
+ rewrite D1; auto with stacking.
symmetry. auto with stacking.
(* agree_incoming *)
- intros. simpl in H4. apply H0. tauto. tauto.
+ intros. simpl in H3. apply H0. tauto. tauto.
(* agree_saved_int *)
- intros. rewrite E2; auto with stacking.
+ intros. rewrite D2; auto with stacking.
+ rewrite C1; auto with stacking.
+ (* agree_saved_float *)
+ intros. rewrite C2; auto with stacking.
Qed.
(** The following lemmas show the correctness of the register reloading
@@ -879,49 +943,66 @@ Qed.
all callee-save registers contain the same values they had at
function entry. *)
-Lemma restore_int_callee_save_correct_rec:
- forall sp parent k fr m rs0 l ls rs,
- incl l int_callee_save_regs ->
+Section RESTORE_CALLEE_SAVE.
+
+Variable bound: frame_env -> Z.
+Variable number: mreg -> Z.
+Variable mkindex: Z -> frame_index.
+Variable ty: typ.
+Variable sp: val.
+Variable csregs: list mreg.
+Hypothesis mkindex_valid:
+ forall r, In r csregs -> number r < bound fe -> index_valid (mkindex (number r)).
+Hypothesis mkindex_typ:
+ forall z, type_of_index (mkindex z) = ty.
+Hypothesis number_within_bounds:
+ forall r, In r csregs ->
+ (number r < bound fe <-> mreg_within_bounds b r).
+Hypothesis mkindex_val:
+ forall ls rs fr ls0 r,
+ agree ls rs fr (parent_frame stack) ls0 -> In r csregs -> number r < bound fe ->
+ index_val (mkindex (number r)) fr = ls0 (R r).
+
+Lemma restore_callee_save_regs_correct:
+ forall k fr m ls0 l ls rs,
+ incl l csregs ->
list_norepet l ->
- agree ls rs fr parent rs0 ->
+ agree ls rs fr (parent_frame stack) ls0 ->
exists ls', exists rs',
- Machabstr.exec_instrs tge tf sp parent
- (List.fold_right (restore_int_callee_save fe) k l) rs fr m
- E0 k rs' fr m
- /\ (forall r, In r l -> rs' r = rs0 r)
+ star step tge
+ (State stack tf sp
+ (restore_callee_save_regs bound number mkindex ty fe l k) rs fr m)
+ E0 (State stack tf sp k rs' fr m)
+ /\ (forall r, In r l -> rs' r = ls0 (R r))
/\ (forall r, ~(In r l) -> rs' r = rs r)
- /\ agree ls' rs' fr parent rs0.
+ /\ agree ls' rs' fr (parent_frame stack) ls0.
Proof.
- induction l.
+ induction l; intros; simpl restore_callee_save_regs.
(* base case *)
- intros. simpl fold_right. exists ls. exists rs.
- split. apply Machabstr.exec_refl.
+ exists ls. exists rs.
+ split. apply star_refl.
split. intros. elim H2.
split. auto. auto.
(* inductive case *)
- intros. simpl fold_right.
- set (k1 := fold_right (restore_int_callee_save fe) k l) in *.
- assert (R0: In a int_callee_save_regs). apply H; auto with coqlib.
- assert (R1: incl l int_callee_save_regs). eauto with coqlib.
+ set (k1 := restore_callee_save_regs bound number mkindex ty fe l k).
+ assert (R0: In a csregs). apply H; auto with coqlib.
+ assert (R1: incl l csregs). eauto with coqlib.
assert (R2: list_norepet l). inversion H0; auto.
- unfold restore_int_callee_save.
- case (zlt (index_int_callee_save a) (fe_num_int_callee_save fe));
- intro;
- unfold fe_num_int_callee_save, fe, make_env in z.
- set (ls1 := Locmap.set (R a) (rs0 a) ls).
- set (rs1 := Regmap.set a (rs0 a) rs).
- assert (R3: agree ls1 rs1 fr parent rs0).
+ unfold restore_callee_save_reg.
+ destruct (zlt (number a) (bound fe)).
+ set (ls1 := Locmap.set (R a) (ls0 (R a)) ls).
+ set (rs1 := Regmap.set a (ls0 (R a)) rs).
+ assert (R3: agree ls1 rs1 fr (parent_frame stack) ls0).
unfold ls1, rs1. apply agree_set_reg. auto.
- red. rewrite int_callee_save_type. exact z.
- apply H. auto with coqlib.
+ rewrite <- number_within_bounds; auto.
generalize (IHl ls1 rs1 R1 R2 R3).
intros [ls' [rs' [A [B [C D]]]]].
- exists ls'. exists rs'.
- split. apply Machabstr.exec_trans with E0 k1 rs1 fr m E0.
+ exists ls'. exists rs'. split.
+ apply star_left with E0 (State stack tf sp k1 rs1 fr m) E0.
unfold rs1; apply exec_Mgetstack'; eauto with stacking.
apply get_slot_index; eauto with stacking.
- symmetry. eauto with stacking.
- eauto with stacking. traceEq.
+ symmetry. eapply mkindex_val; eauto.
+ auto. traceEq.
split. intros. elim H2; intros.
subst r. rewrite C. unfold rs1. apply Regmap.gss. inversion H0; auto.
auto.
@@ -934,127 +1015,82 @@ Proof.
exists ls'; exists rs'. split. assumption.
split. intros. elim H2; intros.
subst r. apply (agree_unused_reg _ _ _ _ _ D).
- unfold mreg_bounded. rewrite int_callee_save_type; auto.
- auto.
+ rewrite <- number_within_bounds. auto. omega. auto.
split. intros. simpl in H2. apply C. tauto.
assumption.
Qed.
+End RESTORE_CALLEE_SAVE.
+
Lemma restore_int_callee_save_correct:
- forall sp parent k fr m rs0 ls rs,
- agree ls rs fr parent rs0 ->
+ forall sp k fr m ls0 ls rs,
+ agree ls rs fr (parent_frame stack) ls0 ->
exists ls', exists rs',
- Machabstr.exec_instrs tge tf sp parent
- (List.fold_right (restore_int_callee_save fe) k int_callee_save_regs) rs fr m
- E0 k rs' fr m
- /\ (forall r, In r int_callee_save_regs -> rs' r = rs0 r)
+ star step tge
+ (State stack tf sp
+ (restore_callee_save_int fe k) rs fr m)
+ E0 (State stack tf sp k rs' fr m)
+ /\ (forall r, In r int_callee_save_regs -> rs' r = ls0 (R r))
/\ (forall r, ~(In r int_callee_save_regs) -> rs' r = rs r)
- /\ agree ls' rs' fr parent rs0.
+ /\ agree ls' rs' fr (parent_frame stack) ls0.
Proof.
- intros. apply restore_int_callee_save_correct_rec with ls.
- apply incl_refl. apply int_callee_save_norepet. auto.
-Qed.
-
-Lemma restore_float_callee_save_correct_rec:
- forall sp parent k fr m rs0 l ls rs,
- incl l float_callee_save_regs ->
- list_norepet l ->
- agree ls rs fr parent rs0 ->
- exists ls', exists rs',
- Machabstr.exec_instrs tge tf sp parent
- (List.fold_right (restore_float_callee_save fe) k l) rs fr m
- E0 k rs' fr m
- /\ (forall r, In r l -> rs' r = rs0 r)
- /\ (forall r, ~(In r l) -> rs' r = rs r)
- /\ agree ls' rs' fr parent rs0.
-Proof.
- induction l.
- (* base case *)
- intros. simpl fold_right. exists ls. exists rs.
- split. apply Machabstr.exec_refl.
- split. intros. elim H2.
- split. auto. auto.
- (* inductive case *)
- intros. simpl fold_right.
- set (k1 := fold_right (restore_float_callee_save fe) k l) in *.
- assert (R0: In a float_callee_save_regs). apply H; auto with coqlib.
- assert (R1: incl l float_callee_save_regs). eauto with coqlib.
- assert (R2: list_norepet l). inversion H0; auto.
- unfold restore_float_callee_save.
- case (zlt (index_float_callee_save a) (fe_num_float_callee_save fe));
- intro;
- unfold fe_num_float_callee_save, fe, make_env in z.
- set (ls1 := Locmap.set (R a) (rs0 a) ls).
- set (rs1 := Regmap.set a (rs0 a) rs).
- assert (R3: agree ls1 rs1 fr parent rs0).
- unfold ls1, rs1. apply agree_set_reg. auto.
- red. rewrite float_callee_save_type. exact z.
- apply H. auto with coqlib.
- generalize (IHl ls1 rs1 R1 R2 R3).
- intros [ls' [rs' [A [B [C D]]]]].
- exists ls'. exists rs'.
- split. apply Machabstr.exec_trans with E0 k1 rs1 fr m E0.
- unfold rs1; apply exec_Mgetstack'; eauto with stacking.
- apply get_slot_index; eauto with stacking.
- symmetry. eauto with stacking.
- exact A. traceEq.
- split. intros. elim H2; intros.
- subst r. rewrite C. unfold rs1. apply Regmap.gss. inversion H0; auto.
+ intros. unfold restore_callee_save_int.
+ apply restore_callee_save_regs_correct with int_callee_save_regs ls.
+ intros; simpl. split; auto. generalize (index_int_callee_save_pos r H0). omega.
auto.
- split. intros. simpl in H2. rewrite C. unfold rs1. apply Regmap.gso.
- apply sym_not_eq; tauto. tauto.
- assumption.
- (* no load takes place *)
- generalize (IHl ls rs R1 R2 H1).
- intros [ls' [rs' [A [B [C D]]]]].
- exists ls'; exists rs'. split. assumption.
- split. intros. elim H2; intros.
- subst r. apply (agree_unused_reg _ _ _ _ _ D).
- unfold mreg_bounded. rewrite float_callee_save_type; auto.
+ intros. unfold mreg_within_bounds.
+ rewrite (int_callee_save_type r H0). tauto.
+ eauto with stacking.
+ apply incl_refl.
+ apply int_callee_save_norepet.
auto.
- split. intros. simpl in H2. apply C. tauto.
- assumption.
Qed.
Lemma restore_float_callee_save_correct:
- forall sp parent k fr m rs0 ls rs,
- agree ls rs fr parent rs0 ->
+ forall sp k fr m ls0 ls rs,
+ agree ls rs fr (parent_frame stack) ls0 ->
exists ls', exists rs',
- Machabstr.exec_instrs tge tf sp parent
- (List.fold_right (restore_float_callee_save fe) k float_callee_save_regs) rs fr m
- E0 k rs' fr m
- /\ (forall r, In r float_callee_save_regs -> rs' r = rs0 r)
+ star step tge
+ (State stack tf sp
+ (restore_callee_save_float fe k) rs fr m)
+ E0 (State stack tf sp k rs' fr m)
+ /\ (forall r, In r float_callee_save_regs -> rs' r = ls0 (R r))
/\ (forall r, ~(In r float_callee_save_regs) -> rs' r = rs r)
- /\ agree ls' rs' fr parent rs0.
+ /\ agree ls' rs' fr (parent_frame stack) ls0.
Proof.
- intros. apply restore_float_callee_save_correct_rec with ls.
- apply incl_refl. apply float_callee_save_norepet. auto.
+ intros. unfold restore_callee_save_float.
+ apply restore_callee_save_regs_correct with float_callee_save_regs ls.
+ intros; simpl. split; auto. generalize (index_float_callee_save_pos r H0). omega.
+ auto.
+ intros. unfold mreg_within_bounds.
+ rewrite (float_callee_save_type r H0). tauto.
+ eauto with stacking.
+ apply incl_refl.
+ apply float_callee_save_norepet.
+ auto.
Qed.
Lemma restore_callee_save_correct:
- forall sp parent k fr m rs0 ls rs,
- agree ls rs fr parent rs0 ->
+ forall sp k fr m ls0 ls rs,
+ agree ls rs fr (parent_frame stack) ls0 ->
exists rs',
- Machabstr.exec_instrs tge tf sp parent
- (restore_callee_save fe k) rs fr m
- E0 k rs' fr m
+ star step tge
+ (State stack tf sp (restore_callee_save fe k) rs fr m)
+ E0 (State stack tf sp k rs' fr m)
/\ (forall r,
In r int_callee_save_regs \/ In r float_callee_save_regs ->
- rs' r = rs0 r)
+ rs' r = ls0 (R r))
/\ (forall r,
~(In r int_callee_save_regs) ->
~(In r float_callee_save_regs) ->
rs' r = rs r).
Proof.
intros. unfold restore_callee_save.
- generalize (restore_int_callee_save_correct sp parent
- (fold_right (restore_float_callee_save fe) k float_callee_save_regs)
- fr m rs0 ls rs H).
+ exploit restore_int_callee_save_correct; eauto.
intros [ls1 [rs1 [A [B [C D]]]]].
- generalize (restore_float_callee_save_correct sp parent
- k fr m rs0 ls1 rs1 D).
+ exploit restore_float_callee_save_correct. eexact D.
intros [ls2 [rs2 [P [Q [R S]]]]].
- exists rs2. split. eapply Machabstr.exec_trans. eexact A. eexact P. traceEq.
+ exists rs2. split. eapply star_trans. eexact A. eexact P. traceEq.
split. intros. elim H0; intros.
rewrite R. apply B. auto. apply list_disjoint_notin with int_callee_save_regs.
apply int_float_callee_save_disjoint. auto.
@@ -1083,12 +1119,12 @@ Remark find_label_save_callee_save:
forall fe lbl k,
Mach.find_label lbl (save_callee_save fe k) = Mach.find_label lbl k.
Proof.
- intros. unfold save_callee_save.
+ intros. unfold save_callee_save, save_callee_save_int, save_callee_save_float, save_callee_save_regs.
repeat rewrite find_label_fold_right. reflexivity.
- intros. unfold save_float_callee_save.
+ intros. unfold save_callee_save_reg.
case (zlt (index_float_callee_save x) (fe_num_float_callee_save fe));
intro; reflexivity.
- intros. unfold save_int_callee_save.
+ intros. unfold save_callee_save_reg.
case (zlt (index_int_callee_save x) (fe_num_int_callee_save fe));
intro; reflexivity.
Qed.
@@ -1097,12 +1133,12 @@ Remark find_label_restore_callee_save:
forall fe lbl k,
Mach.find_label lbl (restore_callee_save fe k) = Mach.find_label lbl k.
Proof.
- intros. unfold restore_callee_save.
+ intros. unfold restore_callee_save, restore_callee_save_int, restore_callee_save_float, restore_callee_save_regs.
repeat rewrite find_label_fold_right. reflexivity.
- intros. unfold restore_float_callee_save.
+ intros. unfold restore_callee_save_reg.
case (zlt (index_float_callee_save x) (fe_num_float_callee_save fe));
intro; reflexivity.
- intros. unfold restore_int_callee_save.
+ intros. unfold restore_callee_save_reg.
case (zlt (index_int_callee_save x) (fe_num_int_callee_save fe));
intro; reflexivity.
Qed.
@@ -1117,13 +1153,14 @@ Proof.
destruct a; unfold transl_instr; auto.
destruct s; simpl; auto.
destruct s; simpl; auto.
+ rewrite find_label_restore_callee_save. auto.
simpl. case (peq lbl l); intro. reflexivity. auto.
rewrite find_label_restore_callee_save. auto.
Qed.
Lemma transl_find_label:
forall f tf lbl c,
- transf_function f = Some tf ->
+ transf_function f = OK tf ->
Linear.find_label lbl f.(Linear.fn_code) = Some c ->
Mach.find_label lbl tf.(Mach.fn_code) =
Some (transl_code (make_env (function_bounds f)) c).
@@ -1143,32 +1180,11 @@ Lemma find_label_incl:
Proof.
induction c; simpl.
intros; discriminate.
- intro c'. case (is_label lbl a); intros.
+ intro c'. case (Linear.is_label lbl a); intros.
injection H; intro; subst c'. red; intros; auto with coqlib.
apply incl_tl. auto.
Qed.
-Lemma exec_instr_incl:
- forall f sp c1 ls1 m1 t c2 ls2 m2,
- Linear.exec_instr ge f sp c1 ls1 m1 t c2 ls2 m2 ->
- incl c1 f.(fn_code) ->
- incl c2 f.(fn_code).
-Proof.
- induction 1; intros; eauto with coqlib.
- eapply find_label_incl; eauto.
- eapply find_label_incl; eauto.
-Qed.
-
-Lemma exec_instrs_incl:
- forall f sp c1 ls1 m1 t c2 ls2 m2,
- Linear.exec_instrs ge f sp c1 ls1 m1 t c2 ls2 m2 ->
- incl c1 f.(fn_code) ->
- incl c2 f.(fn_code).
-Proof.
- induction 1; intros; auto.
- eapply exec_instr_incl; eauto.
-Qed.
-
(** Preservation / translation of global symbols and functions. *)
Lemma symbols_preserved:
@@ -1180,42 +1196,59 @@ Proof.
Qed.
Lemma functions_translated:
- forall f v,
+ forall v f,
Genv.find_funct ge v = Some f ->
exists tf,
- Genv.find_funct tge v = Some tf /\ transf_fundef f = Some tf.
-Proof.
- intros.
- generalize (Genv.find_funct_transf_partial transf_fundef TRANSF H).
- case (transf_fundef f).
- intros tf [A B]. exists tf. tauto.
- intros. tauto.
-Qed.
+ Genv.find_funct tge v = Some tf /\ transf_fundef f = OK tf.
+Proof
+ (Genv.find_funct_transf_partial transf_fundef TRANSF).
Lemma function_ptr_translated:
- forall f v,
+ forall v f,
Genv.find_funct_ptr ge v = Some f ->
exists tf,
- Genv.find_funct_ptr tge v = Some tf /\ transf_fundef f = Some tf.
-Proof.
- intros.
- generalize (Genv.find_funct_ptr_transf_partial transf_fundef TRANSF H).
- case (transf_fundef f).
- intros tf [A B]. exists tf. tauto.
- intros. tauto.
-Qed.
+ Genv.find_funct_ptr tge v = Some tf /\ transf_fundef f = OK tf.
+Proof
+ (Genv.find_funct_ptr_transf_partial transf_fundef TRANSF).
Lemma sig_preserved:
- forall f tf, transf_fundef f = Some tf -> Mach.funsig tf = Linear.funsig f.
+ forall f tf, transf_fundef f = OK tf -> Mach.funsig tf = Linear.funsig f.
Proof.
intros until tf; unfold transf_fundef, transf_partial_fundef.
destruct f. unfold transf_function.
- destruct (zlt (fn_stacksize f) 0). congruence.
- destruct (zlt (- Int.min_signed) (fe_size (make_env (function_bounds f)))). congruence.
- intros. inversion H; reflexivity.
+ destruct (zlt (Linear.fn_stacksize f) 0). simpl; congruence.
+ destruct (zlt (- Int.min_signed) (fe_size (make_env (function_bounds f)))). simpl; congruence.
+ unfold bind. intros. inversion H; reflexivity.
intro. inversion H. reflexivity.
Qed.
+Lemma find_function_translated:
+ forall f0 ls rs fr parent ls0 ros f,
+ agree f0 ls rs fr parent ls0 ->
+ Linear.find_function ge ros ls = Some f ->
+ exists tf,
+ find_function tge ros rs = Some tf /\ transf_fundef f = OK tf.
+Proof.
+ intros until f; intro AG.
+ destruct ros; simpl.
+ rewrite (agree_eval_reg _ _ _ _ _ _ m AG). intro.
+ apply functions_translated; auto.
+ rewrite symbols_preserved. destruct (Genv.find_symbol ge i); try congruence.
+ intro. apply function_ptr_translated; auto.
+Qed.
+
+Hypothesis wt_prog: wt_program prog.
+
+Lemma find_function_well_typed:
+ forall ros ls f,
+ Linear.find_function ge ros ls = Some f -> wt_fundef f.
+Proof.
+ intros until f; destruct ros; simpl; unfold ge.
+ intro. eapply Genv.find_funct_prop; eauto.
+ destruct (Genv.find_symbol (Genv.globalenv prog) i); try congruence.
+ intro. eapply Genv.find_funct_ptr_prop; eauto.
+Qed.
+
(** Correctness of stack pointer relocation in operations and
addressing modes. *)
@@ -1224,7 +1257,7 @@ Definition shift_sp (tf: Mach.function) (sp: val) :=
Remark shift_offset_sp:
forall f tf sp n v,
- transf_function f = Some tf ->
+ transf_function f = OK tf ->
offset_sp sp n = Some v ->
offset_sp (shift_sp tf sp)
(Int.add (Int.repr (fe_size (make_env (function_bounds f)))) n) = Some v.
@@ -1243,11 +1276,11 @@ Proof.
Qed.
Lemma shift_eval_operation:
- forall f tf sp op args v,
- transf_function f = Some tf ->
- eval_operation ge sp op args = Some v ->
+ forall f tf sp op args m v,
+ transf_function f = OK tf ->
+ eval_operation ge sp op args m = Some v ->
eval_operation tge (shift_sp tf sp)
- (transl_op (make_env (function_bounds f)) op) args =
+ (transl_op (make_env (function_bounds f)) op) args m =
Some v.
Proof.
intros until v. destruct op; intros; auto.
@@ -1258,7 +1291,7 @@ Qed.
Lemma shift_eval_addressing:
forall f tf sp addr args v,
- transf_function f = Some tf ->
+ transf_function f = OK tf ->
eval_addressing ge sp addr args = Some v ->
eval_addressing tge (shift_sp tf sp)
(transl_addr (make_env (function_bounds f)) addr) args =
@@ -1282,7 +1315,7 @@ Variable rs: regset.
Variable sg: signature.
Hypothesis AG1: forall r, rs r = ls (R r).
Hypothesis AG2: forall (ofs : Z) (ty : typ),
- 6 <= ofs ->
+ 14 <= ofs ->
ofs + typesize ty <= size_arguments sg ->
get_slot fr ty (Int.signed (Int.repr (4 * ofs)))
(ls (S (Outgoing ofs ty))).
@@ -1319,374 +1352,336 @@ End EXTERNAL_ARGUMENTS.
(** The proof of semantic preservation relies on simulation diagrams
of the following form:
<<
- c, ls, m ------------------- T(c), rs, fr, m
- | |
- | |
- v v
- c', ls', m' ---------------- T(c'), rs', fr', m'
+ st1 --------------- st2
+ | |
+ t| +|t
+ | |
+ v v
+ st1'--------------- st2'
>>
- The left vertical arrow represents a transition in the
- original Linear code. The top horizontal bar captures three preconditions:
-- Agreement between [ls] on the Linear side and [rs], [fr], [rs0]
- on the Mach side.
-- Inclusion between [c] and the code of the function [f] being
- translated.
+ Matching between source and target states is defined by [match_states]
+ below. It implies:
+- Agreement between, on the Linear side, the location sets [ls]
+ and [parent_locset s] of the current function and its caller,
+ and on the Mach side the register set [rs], the frame [fr]
+ and the caller's frame [parent_frame ts].
+- Inclusion between the Linear code [c] and the code of the
+ function [f] being executed.
- Well-typedness of [f].
-
- In conclusion, we want to prove the existence of [rs'], [fr'], [m']
- that satisfies the right arrow (zero, one or several transitions in
- the generated Mach code) and the postcondition (agreement between
- [ls'] and [rs'], [fr'], [rs0]).
-
- As usual, we capture these diagrams as predicates parameterized
- by the transition in the original Linear code. *)
-
-Definition exec_instr_prop
- (f: function) (sp: val)
- (c: code) (ls: locset) (m: mem) (t: trace)
- (c': code) (ls': locset) (m': mem) :=
- forall tf rs fr parent rs0
- (TRANSL: transf_function f = Some tf)
- (WTF: wt_function f)
- (AG: agree f ls rs fr parent rs0)
- (INCL: incl c f.(fn_code)),
- exists rs', exists fr',
- Machabstr.exec_instrs tge tf (shift_sp tf sp) parent
- (transl_code (make_env (function_bounds f)) c) rs fr m
- t (transl_code (make_env (function_bounds f)) c') rs' fr' m'
- /\ agree f ls' rs' fr' parent rs0.
-
-(** The simulation property for function calls has different preconditions
- (a slightly weaker notion of agreement between [ls] and the initial
- register values [rs] and caller's frame [parent]) and different
- postconditions (preservation of callee-save registers). *)
-
-Definition exec_function_prop
- (f: fundef)
- (ls: locset) (m: mem) (t: trace)
- (ls': locset) (m': mem) :=
- forall tf rs parent
- (TRANSL: transf_fundef f = Some tf)
- (WTF: wt_fundef f)
- (AG1: forall r, rs r = ls (R r))
- (AG2: forall ofs ty,
- 6 <= ofs ->
- ofs + typesize ty <= size_arguments (funsig f) ->
- get_slot parent ty (Int.signed (Int.repr (4 * ofs))) (ls (S (Outgoing ofs ty)))),
- exists rs',
- Machabstr.exec_function tge tf parent rs m t rs' m'
- /\ (forall r,
- In (R r) temporaries \/ In (R r) destroyed_at_call ->
- rs' r = ls' (R r))
- /\ (forall r,
- In r int_callee_save_regs \/ In r float_callee_save_regs ->
- rs' r = rs r).
-
-Hypothesis wt_prog: wt_program prog.
-
-Lemma transf_function_correct:
- forall f ls m t ls' m',
- Linear.exec_function ge f ls m t ls' m' ->
- exec_function_prop f ls m t ls' m'.
+*)
+
+Inductive match_stacks: list Linear.stackframe -> list Machabstr.stackframe -> Prop :=
+ | match_stacks_nil:
+ match_stacks nil nil
+ | match_stacks_cons:
+ forall f sp c ls tf fr s ts,
+ match_stacks s ts ->
+ transf_function f = OK tf ->
+ wt_function f ->
+ agree_frame f ls fr (parent_frame ts) (parent_locset s) ->
+ incl c (Linear.fn_code f) ->
+ match_stacks
+ (Linear.Stackframe f sp ls c :: s)
+ (Machabstr.Stackframe tf (shift_sp tf sp) (transl_code (make_env (function_bounds f)) c) fr :: ts).
+
+Inductive match_states: Linear.state -> Machabstr.state -> Prop :=
+ | match_states_intro:
+ forall s f sp c ls m ts tf rs fr
+ (STACKS: match_stacks s ts)
+ (TRANSL: transf_function f = OK tf)
+ (WTF: wt_function f)
+ (AG: agree f ls rs fr (parent_frame ts) (parent_locset s))
+ (INCL: incl c (Linear.fn_code f)),
+ match_states (Linear.State s f sp c ls m)
+ (Machabstr.State ts tf (shift_sp tf sp) (transl_code (make_env (function_bounds f)) c) rs fr m)
+ | match_states_call:
+ forall s f ls m ts tf rs
+ (STACKS: match_stacks s ts)
+ (TRANSL: transf_fundef f = OK tf)
+ (WTF: wt_fundef f)
+ (AG1: forall r, rs r = ls (R r))
+ (AG2: forall ofs ty,
+ 14 <= ofs ->
+ ofs + typesize ty <= size_arguments (Linear.funsig f) ->
+ get_slot (parent_frame ts) ty (Int.signed (Int.repr (4 * ofs))) (ls (S (Outgoing ofs ty))))
+ (AG3: agree_callee_save ls (parent_locset s)),
+ match_states (Linear.Callstate s f ls m)
+ (Machabstr.Callstate ts tf rs m)
+ | match_states_return:
+ forall s ls m ts rs
+ (STACKS: match_stacks s ts)
+ (AG1: forall r, rs r = ls (R r))
+ (AG2: agree_callee_save ls (parent_locset s)),
+ match_states (Linear.Returnstate s ls m)
+ (Machabstr.Returnstate ts rs m).
+
+Theorem transf_step_correct:
+ forall s1 t s2, Linear.step ge s1 t s2 ->
+ forall s1' (MS: match_states s1 s1'),
+ exists s2', plus step tge s1' t s2' /\ match_states s2 s2'.
Proof.
assert (RED: forall f i c,
transl_code (make_env (function_bounds f)) (i :: c) =
transl_instr (make_env (function_bounds f)) i
(transl_code (make_env (function_bounds f)) c)).
intros. reflexivity.
- apply (Linear.exec_function_ind3 ge exec_instr_prop
- exec_instr_prop exec_function_prop);
- intros; red; intros;
- try rewrite RED;
+ induction 1; intros;
+ try inv MS;
+ try rewrite RED;
try (generalize (WTF _ (INCL _ (in_eq _ _))); intro WTI);
+ try (generalize (function_is_within_bounds f WTF _ (INCL _ (in_eq _ _)));
+ intro BOUND; simpl in BOUND);
unfold transl_instr.
-
(* Lgetstack *)
- inversion WTI. exists (rs0#r <- (rs (S sl))); exists fr.
+ inv WTI. destruct BOUND.
+ exists (State ts tf (shift_sp tf sp) (transl_code (make_env (function_bounds f)) b)
+ (rs0#r <- (rs (S sl))) fr m).
split. destruct sl.
(* Lgetstack, local *)
- apply exec_Mgetstack'; auto.
+ apply plus_one. eapply exec_Mgetstack'; eauto.
apply get_slot_index. apply index_local_valid. auto.
eapply agree_size; eauto. reflexivity.
eapply agree_locals; eauto.
(* Lgetstack, incoming *)
- apply Machabstr.exec_one; constructor.
+ apply plus_one; apply exec_Mgetparam.
unfold offset_of_index. eapply agree_incoming; eauto.
(* Lgetstack, outgoing *)
- apply exec_Mgetstack'; auto.
+ apply plus_one; apply exec_Mgetstack'; eauto.
apply get_slot_index. apply index_arg_valid. auto.
eapply agree_size; eauto. reflexivity.
eapply agree_outgoing; eauto.
(* Lgetstack, common *)
+ econstructor; eauto with coqlib.
apply agree_set_reg; auto.
(* Lsetstack *)
- inversion WTI. destruct sl.
+ inv WTI. destruct sl.
+
(* Lsetstack, local *)
- generalize (agree_set_local _ _ _ _ _ _ (rs0 r) _ _ AG H3).
+ generalize (agree_set_local _ _ _ _ _ _ (rs0 r) _ _ AG BOUND).
intros [fr' [SET AG']].
- exists rs0; exists fr'. split.
- apply exec_Msetstack'; auto.
+ econstructor; split.
+ apply plus_one. eapply exec_Msetstack'; eauto.
+ econstructor; eauto with coqlib.
replace (rs (R r)) with (rs0 r). auto.
symmetry. eapply agree_reg; eauto.
(* Lsetstack, incoming *)
contradiction.
(* Lsetstack, outgoing *)
- generalize (agree_set_outgoing _ _ _ _ _ _ (rs0 r) _ _ AG H3).
+ generalize (agree_set_outgoing _ _ _ _ _ _ (rs0 r) _ _ AG BOUND).
intros [fr' [SET AG']].
- exists rs0; exists fr'. split.
- apply exec_Msetstack'; auto.
+ econstructor; split.
+ apply plus_one. eapply exec_Msetstack'; eauto.
+ econstructor; eauto with coqlib.
replace (rs (R r)) with (rs0 r). auto.
symmetry. eapply agree_reg; eauto.
(* Lop *)
- assert (mreg_bounded f res). inversion WTI; auto.
- exists (rs0#res <- v); exists fr. split.
- apply Machabstr.exec_one. constructor.
+ exists (State ts tf (shift_sp tf sp) (transl_code (make_env (function_bounds f)) b) (rs0#res <- v) fr m); split.
+ apply plus_one. apply exec_Mop.
apply shift_eval_operation. auto.
change mreg with RegEq.t.
rewrite (agree_eval_regs _ _ _ _ _ _ args AG). auto.
+ econstructor; eauto with coqlib.
apply agree_set_reg; auto.
(* Lload *)
- inversion WTI. exists (rs0#dst <- v); exists fr. split.
- apply Machabstr.exec_one; econstructor.
+ exists (State ts tf (shift_sp tf sp) (transl_code (make_env (function_bounds f)) b) (rs0#dst <- v) fr m); split.
+ apply plus_one; eapply exec_Mload; eauto.
apply shift_eval_addressing; auto.
change mreg with RegEq.t.
rewrite (agree_eval_regs _ _ _ _ _ _ args AG). eauto.
- auto.
+ econstructor; eauto with coqlib.
apply agree_set_reg; auto.
(* Lstore *)
- exists rs0; exists fr. split.
- apply Machabstr.exec_one; econstructor.
- apply shift_eval_addressing; auto.
+ econstructor; split.
+ apply plus_one; eapply exec_Mstore; eauto.
+ apply shift_eval_addressing; eauto.
change mreg with RegEq.t.
rewrite (agree_eval_regs _ _ _ _ _ _ args AG). eauto.
- rewrite (agree_eval_reg _ _ _ _ _ _ src AG). auto.
- auto.
-
- (* Lcall *)
- inversion WTI.
- assert (WTF': wt_fundef f').
- destruct ros; simpl in H.
- apply (Genv.find_funct_prop wt_fundef wt_prog H).
- destruct (Genv.find_symbol ge i); try discriminate.
- apply (Genv.find_funct_ptr_prop wt_fundef wt_prog H).
- assert (TR: exists tf', Mach.find_function tge ros rs0 = Some tf'
- /\ transf_fundef f' = Some tf').
- destruct ros; simpl in H; simpl.
- eapply functions_translated.
- rewrite (agree_eval_reg _ _ _ _ _ _ m0 AG). auto.
- rewrite symbols_preserved.
- destruct (Genv.find_symbol ge i); try discriminate.
- apply function_ptr_translated; auto.
- elim TR; intros tf' [FIND' TRANSL']; clear TR.
- assert (AG1: forall r, rs0 r = rs (R r)).
- intro. symmetry. eapply agree_reg; eauto.
- assert (AG2: forall ofs ty,
- 6 <= ofs ->
- ofs + typesize ty <= size_arguments (funsig f') ->
- get_slot fr ty (Int.signed (Int.repr (4 * ofs))) (rs (S (Outgoing ofs ty)))).
- intros.
- assert (slot_bounded f (Outgoing ofs ty)).
- red. rewrite <- H0 in H8. omega.
- change (4 * ofs) with (offset_of_index (make_env (function_bounds f)) (FI_arg ofs ty)).
- rewrite (offset_of_index_no_overflow f tf); auto.
- apply get_slot_index. apply index_arg_valid. auto.
- eapply agree_size; eauto. reflexivity.
- eapply agree_outgoing; eauto.
- generalize (H2 tf' rs0 fr TRANSL' WTF' AG1 AG2).
- intros [rs2 [EXF [REGS1 REGS2]]].
- exists rs2; exists fr. split.
- apply Machabstr.exec_one; apply Machabstr.exec_Mcall with tf'; auto.
- apply agree_return_regs with rs0; auto.
-
+ rewrite (agree_eval_reg _ _ _ _ _ _ src AG). eauto.
+ econstructor; eauto with coqlib.
+
+ (* Lcall *)
+ assert (WTF': wt_fundef f'). eapply find_function_well_typed; eauto.
+ exploit find_function_translated; eauto.
+ intros [tf' [FIND' TRANSL']].
+ econstructor; split.
+ apply plus_one; eapply exec_Mcall; eauto.
+ econstructor; eauto.
+ econstructor; eauto with coqlib.
+ exists rs0; auto.
+ intro. symmetry. eapply agree_reg; eauto.
+ intros.
+ assert (slot_within_bounds f (function_bounds f) (Outgoing ofs ty)).
+ red. simpl. omega.
+ change (4 * ofs) with (offset_of_index (make_env (function_bounds f)) (FI_arg ofs ty)).
+ rewrite (offset_of_index_no_overflow f tf); auto.
+ apply get_slot_index. apply index_arg_valid. auto.
+ eapply agree_size; eauto. reflexivity.
+ eapply agree_outgoing; eauto.
+ simpl. red; auto.
+
+ (* Ltailcall *)
+ assert (WTF': wt_fundef f'). eapply find_function_well_typed; eauto.
+ generalize (find_function_translated _ _ _ _ _ _ _ _ AG H).
+ intros [tf' [FIND' TRANSL']].
+ generalize (restore_callee_save_correct ts _ _ TRANSL
+ (shift_sp tf (Vptr stk Int.zero))
+ (Mtailcall (Linear.funsig f') ros :: transl_code (make_env (function_bounds f)) b)
+ _ m _ _ _ AG).
+ intros [rs2 [A [B C]]].
+ assert (FIND'': find_function tge ros rs2 = Some tf').
+ rewrite <- FIND'. destruct ros; simpl; auto.
+ inv WTI. rewrite C. auto.
+ simpl. intuition congruence. simpl. intuition congruence.
+ econstructor; split.
+ eapply plus_right. eexact A.
+ simpl shift_sp. eapply exec_Mtailcall; eauto. traceEq.
+ econstructor; eauto.
+ intros; symmetry; eapply agree_return_regs; eauto.
+ intros. inv WTI. rewrite tailcall_possible_size in H4.
+ rewrite H4 in H1. elimtype False. generalize (typesize_pos ty). omega.
+ apply agree_callee_save_return_regs.
+
(* Lalloc *)
- exists (rs0#loc_alloc_result <- (Vptr blk Int.zero)); exists fr. split.
- apply Machabstr.exec_one; eapply Machabstr.exec_Malloc; eauto.
+ exists (State ts tf (shift_sp tf sp) (transl_code (make_env (function_bounds f)) b)
+ (rs0#loc_alloc_result <- (Vptr blk Int.zero)) fr m'); split.
+ apply plus_one; eapply exec_Malloc; eauto.
rewrite (agree_eval_reg _ _ _ _ _ _ loc_alloc_argument AG). auto.
+ econstructor; eauto with coqlib.
apply agree_set_reg; auto.
red. simpl. generalize (max_over_regs_of_funct_pos f int_callee_save). omega.
(* Llabel *)
- exists rs0; exists fr. split.
- apply Machabstr.exec_one; apply Machabstr.exec_Mlabel.
- auto.
+ econstructor; split.
+ apply plus_one; apply exec_Mlabel.
+ econstructor; eauto with coqlib.
(* Lgoto *)
- exists rs0; exists fr. split.
- apply Machabstr.exec_one; apply Machabstr.exec_Mgoto.
- apply transl_find_label; auto.
- auto.
+ econstructor; split.
+ apply plus_one; apply exec_Mgoto.
+ apply transl_find_label; eauto.
+ econstructor; eauto.
+ eapply find_label_incl; eauto.
(* Lcond, true *)
- exists rs0; exists fr. split.
- apply Machabstr.exec_one; apply Machabstr.exec_Mcond_true.
- rewrite <- (agree_eval_regs _ _ _ _ _ _ args AG) in H; auto.
- apply transl_find_label; auto.
- auto.
+ econstructor; split.
+ apply plus_one; apply exec_Mcond_true.
+ rewrite <- (agree_eval_regs _ _ _ _ _ _ args AG) in H; eauto.
+ apply transl_find_label; eauto.
+ econstructor; eauto.
+ eapply find_label_incl; eauto.
(* Lcond, false *)
- exists rs0; exists fr. split.
- apply Machabstr.exec_one; apply Machabstr.exec_Mcond_false.
+ econstructor; split.
+ apply plus_one; apply exec_Mcond_false.
rewrite <- (agree_eval_regs _ _ _ _ _ _ args AG) in H; auto.
- auto.
-
- (* refl *)
- exists rs0; exists fr. split. apply Machabstr.exec_refl. auto.
-
- (* one *)
- apply H0; auto.
-
- (* trans *)
- generalize (H0 tf rs fr parent rs0 TRANSL WTF AG INCL).
- intros [rs' [fr' [A B]]].
- assert (INCL': incl b2 (fn_code f)). eapply exec_instrs_incl; eauto.
- generalize (H2 tf rs' fr' parent rs0 TRANSL WTF B INCL').
- intros [rs'' [fr'' [C D]]].
- exists rs''; exists fr''. split.
- eapply Machabstr.exec_trans. eexact A. eexact C. auto.
- auto.
-
- (* function *)
+ econstructor; eauto with coqlib.
+
+ (* Lreturn *)
+ exploit restore_callee_save_correct; eauto.
+ intros [ls' [A [B C]]].
+ econstructor; split.
+ eapply plus_right. eauto.
+ simpl shift_sp. econstructor; eauto. traceEq.
+ econstructor; eauto.
+ intros. symmetry. eapply agree_return_regs; eauto.
+ apply agree_callee_save_return_regs.
+
+ (* internal function *)
generalize TRANSL; clear TRANSL.
unfold transf_fundef, transf_partial_fundef.
- caseEq (transf_function f); try congruence.
+ caseEq (transf_function f); simpl; try congruence.
intros tfn TRANSL EQ. inversion EQ; clear EQ; subst tf.
inversion WTF as [|f' WTFN]. subst f'.
- assert (X: forall link ra,
- exists rs' : regset,
- Machabstr.exec_function_body tge tfn parent link ra rs0 m t rs' (free m2 stk) /\
- (forall r : mreg,
- In (R r) temporaries \/ In (R r) destroyed_at_call -> rs' r = rs2 (R r)) /\
- (forall r : mreg,
- In r int_callee_save_regs \/ In r float_callee_save_regs -> rs' r = rs0 r)).
- intros.
set (sp := Vptr stk Int.zero) in *.
set (tsp := shift_sp tfn sp).
set (fe := make_env (function_bounds f)).
- assert (low (init_frame tfn) = -fe.(fe_size)).
- simpl low. rewrite (unfold_transf_function _ _ TRANSL).
+ assert (fr_low (init_frame tfn) = - fe.(fe_size)).
+ simpl fr_low. rewrite (unfold_transf_function _ _ TRANSL).
reflexivity.
- assert (exists fr1, set_slot (init_frame tfn) Tint 0 link fr1).
- apply set_slot_ok. reflexivity. omega. rewrite H2. generalize (size_pos f).
- unfold fe. simpl typesize. omega.
- elim H3; intros fr1 SET1; clear H3.
- assert (high fr1 = 0).
- inversion SET1. reflexivity.
- assert (low fr1 = -fe.(fe_size)).
- inversion SET1. rewrite <- H2. reflexivity.
- assert (exists fr2, set_slot fr1 Tint 12 ra fr2).
- apply set_slot_ok. auto. omega. rewrite H4. generalize (size_pos f).
- unfold fe. simpl typesize. omega.
- elim H5; intros fr2 SET2; clear H5.
- assert (high fr2 = 0).
- inversion SET2. simpl. auto.
- assert (low fr2 = -fe.(fe_size)).
- inversion SET2. rewrite <- H4. reflexivity.
- assert (UNDEF: forall idx, index_valid f idx -> index_val f idx fr2 = Vundef).
- intros.
- assert (get_slot fr2 (type_of_index idx) (offset_of_index fe idx) Vundef).
- generalize (offset_of_index_valid _ _ H7). fold fe. intros [XX YY].
- eapply slot_gso; eauto.
- eapply slot_gso; eauto.
- apply slot_gi. omega. omega.
- simpl typesize. omega. simpl typesize. omega.
- inversion H8. symmetry. exact H11.
- generalize (save_callee_save_correct f tfn TRANSL
- tsp parent
- (transl_code (make_env (function_bounds f)) f.(fn_code))
- rs0 fr2 m1 rs AG1 AG2 H5 H6 UNDEF).
+ assert (UNDEF: forall idx, index_valid f idx -> index_val f idx (init_frame tfn) = Vundef).
+ intros.
+ assert (get_slot (init_frame tfn) (type_of_index idx) (offset_of_index fe idx) Vundef).
+ generalize (offset_of_index_valid _ _ H1). fold fe. intros [XX YY].
+ apply slot_gi; auto. omega.
+ inv H2; auto.
+ exploit save_callee_save_correct; eauto.
intros [fr [EXP AG]].
- generalize (H1 tfn rs0 fr parent rs0 TRANSL WTFN AG (incl_refl _)).
- intros [rs' [fr' [EXB AG']]].
- generalize (restore_callee_save_correct f tfn TRANSL tsp parent
- (Mreturn :: transl_code (make_env (function_bounds f)) b)
- fr' m2 rs0 rs2 rs' AG').
- intros [rs'' [EXX [REGS1 REGS2]]].
- exists rs''. split. eapply Machabstr.exec_funct_body.
- rewrite (unfold_transf_function f tfn TRANSL); eexact H.
- eexact SET1. eexact SET2.
- replace (Mach.fn_code tfn) with
- (transl_body f (make_env (function_bounds f))).
- replace (Vptr stk (Int.repr (- fn_framesize tfn))) with tsp.
- eapply Machabstr.exec_trans. eexact EXP.
- eapply Machabstr.exec_trans. eexact EXB. eexact EXX.
- reflexivity. traceEq.
- unfold tsp, shift_sp, sp. unfold Val.add.
- rewrite Int.add_commut. rewrite Int.add_zero. auto.
- rewrite (unfold_transf_function f tfn TRANSL). simpl. auto.
- split. intros. rewrite REGS2. symmetry; eapply agree_reg; eauto.
- apply int_callee_save_not_destroyed; auto.
- apply float_callee_save_not_destroyed; auto.
- auto.
- generalize (X Vzero Vzero). intros [rs' [EX [REGS1 REGS2]]].
- exists rs'. split.
- constructor. intros.
- generalize (X link ra). intros [rs'' [EX' [REGS1' REGS2']]].
- assert (rs' = rs'').
- apply (@Regmap.exten val). intro r.
- elim (register_classification r); intro.
- rewrite REGS1'. apply REGS1. auto. auto.
- rewrite REGS2'. apply REGS2. auto. auto.
- rewrite H4. auto.
- split; auto.
+ econstructor; split.
+ eapply plus_left.
+ eapply exec_function_internal; eauto.
+ rewrite (unfold_transf_function f tfn TRANSL); simpl; eexact H.
+ replace (Mach.fn_code tfn) with
+ (transl_body f (make_env (function_bounds f))).
+ replace (Vptr stk (Int.repr (- fn_framesize tfn))) with tsp.
+ unfold transl_body. eexact EXP.
+ unfold tsp, shift_sp, sp. unfold Val.add.
+ rewrite Int.add_commut. rewrite Int.add_zero. auto.
+ rewrite (unfold_transf_function f tfn TRANSL). simpl. auto.
+ traceEq.
+ unfold tsp. econstructor; eauto with coqlib.
+ eapply agree_callee_save_agree; eauto.
(* external function *)
simpl in TRANSL. inversion TRANSL; subst tf.
- inversion WTF. subst ef0. set (sg := ef_sig ef) in *.
- exists (rs#(loc_result sg) <- res).
- split. econstructor. eauto.
- fold sg. rewrite H0. apply transl_external_arguments; assumption.
- reflexivity.
- split; intros. rewrite H1.
- unfold Regmap.set. case (RegEq.eq r (loc_result sg)); intro.
+ inversion WTF. subst ef0.
+ exploit transl_external_arguments; eauto. intro EXTARGS.
+ econstructor; split.
+ apply plus_one. eapply exec_function_external; eauto.
+ econstructor; eauto.
+ intros. unfold Regmap.set. case (RegEq.eq r (loc_result (ef_sig ef))); intro.
rewrite e. rewrite Locmap.gss; auto. rewrite Locmap.gso; auto.
red; auto.
- apply Regmap.gso. red; intro; subst r.
- elim (Conventions.loc_result_not_callee_save _ H2).
+ apply agree_callee_save_set_result; auto.
+
+ (* return *)
+ inv STACKS.
+ econstructor; split.
+ apply plus_one. apply exec_return.
+ econstructor; eauto. simpl in AG2.
+ eapply agree_frame_agree; eauto.
Qed.
-End PRESERVATION.
+Lemma transf_initial_states:
+ forall st1, Linear.initial_state prog st1 ->
+ exists st2, Machabstr.initial_state tprog st2 /\ match_states st1 st2.
+Proof.
+ intros. inversion H.
+ exploit function_ptr_translated; eauto. intros [tf [FIND TR]].
+ econstructor; split.
+ econstructor.
+ rewrite (transform_partial_program_main _ _ TRANSF).
+ rewrite symbols_preserved. eauto.
+ eauto.
+ rewrite (Genv.init_mem_transf_partial _ _ TRANSF).
+ econstructor; eauto. constructor.
+ eapply Genv.find_funct_ptr_prop; eauto.
+ intros.
+ replace (size_arguments (Linear.funsig f)) with 14 in H5.
+ elimtype False. generalize (typesize_pos ty). omega.
+ rewrite H2; auto.
+ simpl; red; auto.
+Qed.
-Theorem transl_program_correct:
- forall (p: Linear.program) (tp: Mach.program) (t: trace) (r: val),
- wt_program p ->
- transf_program p = Some tp ->
- Linear.exec_program p t r ->
- Machabstr.exec_program tp t r.
-Proof.
- intros p tp t r WTP TRANSF
- [fptr [f [ls' [m [FINDSYMB [FINDFUNC [SIG [EXEC RES]]]]]]]].
- assert (WTF: wt_fundef f).
- apply (Genv.find_funct_ptr_prop wt_fundef WTP FINDFUNC).
- set (ls := Locmap.init Vundef) in *.
- set (rs := Regmap.init Vundef).
- set (fr := empty_frame).
- assert (AG1: forall r, rs r = ls (R r)).
- intros; reflexivity.
- assert (AG2: forall ofs ty,
- 6 <= ofs ->
- ofs + typesize ty <= size_arguments (funsig f) ->
- get_slot fr ty (Int.signed (Int.repr (4 * ofs))) (ls (S (Outgoing ofs ty)))).
- rewrite SIG. unfold size_arguments, sig_args, size_arguments_rec.
- intros. generalize (typesize_pos ty).
- intro. omegaContradiction.
- generalize (function_ptr_translated p tp TRANSF f _ FINDFUNC).
- intros [tf [TFIND TRANSL]].
- generalize (transf_function_correct p tp TRANSF WTP _ _ _ _ _ _ EXEC
- tf rs fr TRANSL WTF AG1 AG2).
- intros [rs' [A [B C]]].
- red. exists fptr; exists tf; exists rs'; exists m.
- split. rewrite (symbols_preserved p tp TRANSF).
- rewrite (transform_partial_program_main transf_fundef p TRANSF).
- assumption.
- split. assumption.
- split. replace (Genv.init_mem tp) with (Genv.init_mem p).
- exact A. symmetry. apply Genv.init_mem_transf_partial with transf_fundef.
- exact TRANSF.
- rewrite <- RES. replace R3 with (loc_result (funsig f)).
- apply B. right. apply loc_result_acceptable.
- rewrite SIG; reflexivity.
+Lemma transf_final_states:
+ forall st1 st2 r,
+ match_states st1 st2 -> Linear.final_state st1 r -> Machabstr.final_state st2 r.
+Proof.
+ intros. inv H0. inv H. inv STACKS. econstructor. rewrite AG1; auto.
+Qed.
+
+Theorem transf_program_correct:
+ forall (beh: program_behavior),
+ Linear.exec_program prog beh -> Machabstr.exec_program tprog beh.
+Proof.
+ unfold Linear.exec_program, Machabstr.exec_program; intros.
+ eapply simulation_plus_preservation; eauto.
+ eexact transf_initial_states.
+ eexact transf_final_states.
+ eexact transf_step_correct.
Qed.
+
+End PRESERVATION.
diff --git a/backend/Stackingtyping.v b/backend/Stackingtyping.v
index beb28e2..fa8a3e2 100644
--- a/backend/Stackingtyping.v
+++ b/backend/Stackingtyping.v
@@ -2,6 +2,7 @@
Require Import Coqlib.
Require Import Maps.
+Require Import Errors.
Require Import Integers.
Require Import AST.
Require Import Op.
@@ -11,11 +12,12 @@ Require Import Linear.
Require Import Lineartyping.
Require Import Mach.
Require Import Machtyping.
+Require Import Bounds.
Require Import Stacking.
Require Import Stackingproof.
(** We show that the Mach code generated by the [Stacking] pass
- is well-typed if the original Linear code is. *)
+ is well-typed if the original LTLin code is. *)
Definition wt_instrs (k: Mach.code) : Prop :=
forall i, In i k -> wt_instr i.
@@ -33,17 +35,7 @@ Section TRANSL_FUNCTION.
Variable f: Linear.function.
Let fe := make_env (function_bounds f).
Variable tf: Mach.function.
-Hypothesis TRANSF_F: transf_function f = Some tf.
-
-Lemma wt_Msetstack':
- forall idx ty r,
- mreg_type r = ty -> index_valid f idx ->
- wt_instr (Msetstack r (Int.repr (offset_of_index fe idx)) ty).
-Proof.
- intros. constructor. auto.
- unfold fe. rewrite (offset_of_index_no_overflow f tf TRANSF_F); auto.
- generalize (offset_of_index_valid f idx H0). tauto.
-Qed.
+Hypothesis TRANSF_F: transf_function f = OK tf.
Lemma wt_fold_right:
forall (A: Set) (f: A -> code -> code) (k: code) (l: list A),
@@ -58,51 +50,57 @@ Proof.
auto.
Qed.
-Lemma wt_save_int_callee_save:
- forall cs k,
- In cs int_callee_save_regs -> wt_instrs k ->
- wt_instrs (save_int_callee_save fe cs k).
+Lemma wt_save_callee_save_int:
+ forall k,
+ wt_instrs k ->
+ wt_instrs (save_callee_save_int fe k).
Proof.
- intros. unfold save_int_callee_save.
- case (zlt (index_int_callee_save cs) (fe_num_int_callee_save fe)); intro.
+ intros. unfold save_callee_save_int, save_callee_save_regs.
+ apply wt_fold_right; auto.
+ intros. unfold save_callee_save_reg.
+ case (zlt (index_int_callee_save x) (fe_num_int_callee_save fe)); intro.
apply wt_instrs_cons; auto.
- apply wt_Msetstack'. apply int_callee_save_type; auto.
- apply index_saved_int_valid. auto. exact z.
+ apply wt_Msetstack. apply int_callee_save_type; auto.
auto.
Qed.
-Lemma wt_save_float_callee_save:
- forall cs k,
- In cs float_callee_save_regs -> wt_instrs k ->
- wt_instrs (save_float_callee_save fe cs k).
+Lemma wt_save_callee_save_float:
+ forall k,
+ wt_instrs k ->
+ wt_instrs (save_callee_save_float fe k).
Proof.
- intros. unfold save_float_callee_save.
- case (zlt (index_float_callee_save cs) (fe_num_float_callee_save fe)); intro.
+ intros. unfold save_callee_save_float, save_callee_save_regs.
+ apply wt_fold_right; auto.
+ intros. unfold save_callee_save_reg.
+ case (zlt (index_float_callee_save x) (fe_num_float_callee_save fe)); intro.
apply wt_instrs_cons; auto.
- apply wt_Msetstack'. apply float_callee_save_type; auto.
- apply index_saved_float_valid. auto. exact z.
+ apply wt_Msetstack. apply float_callee_save_type; auto.
auto.
Qed.
-Lemma wt_restore_int_callee_save:
- forall cs k,
- In cs int_callee_save_regs -> wt_instrs k ->
- wt_instrs (restore_int_callee_save fe cs k).
+Lemma wt_restore_callee_save_int:
+ forall k,
+ wt_instrs k ->
+ wt_instrs (restore_callee_save_int fe k).
Proof.
- intros. unfold restore_int_callee_save.
- case (zlt (index_int_callee_save cs) (fe_num_int_callee_save fe)); intro.
+ intros. unfold restore_callee_save_int, restore_callee_save_regs.
+ apply wt_fold_right; auto.
+ intros. unfold restore_callee_save_reg.
+ case (zlt (index_int_callee_save x) (fe_num_int_callee_save fe)); intro.
apply wt_instrs_cons; auto.
constructor. apply int_callee_save_type; auto.
auto.
Qed.
-Lemma wt_restore_float_callee_save:
- forall cs k,
- In cs float_callee_save_regs -> wt_instrs k ->
- wt_instrs (restore_float_callee_save fe cs k).
+Lemma wt_restore_callee_save_float:
+ forall k,
+ wt_instrs k ->
+ wt_instrs (restore_callee_save_float fe k).
Proof.
- intros. unfold restore_float_callee_save.
- case (zlt (index_float_callee_save cs) (fe_num_float_callee_save fe)); intro.
+ intros. unfold restore_callee_save_float, restore_callee_save_regs.
+ apply wt_fold_right; auto.
+ intros. unfold restore_callee_save_reg.
+ case (zlt (index_float_callee_save x) (fe_num_float_callee_save fe)); intro.
apply wt_instrs_cons; auto.
constructor. apply float_callee_save_type; auto.
auto.
@@ -113,9 +111,7 @@ Lemma wt_save_callee_save:
wt_instrs k -> wt_instrs (save_callee_save fe k).
Proof.
intros. unfold save_callee_save.
- apply wt_fold_right. exact wt_save_int_callee_save.
- apply wt_fold_right. exact wt_save_float_callee_save.
- auto.
+ apply wt_save_callee_save_int. apply wt_save_callee_save_float. auto.
Qed.
Lemma wt_restore_callee_save:
@@ -123,37 +119,34 @@ Lemma wt_restore_callee_save:
wt_instrs k -> wt_instrs (restore_callee_save fe k).
Proof.
intros. unfold restore_callee_save.
- apply wt_fold_right. exact wt_restore_int_callee_save.
- apply wt_fold_right. exact wt_restore_float_callee_save.
- auto.
+ apply wt_restore_callee_save_int. apply wt_restore_callee_save_float. auto.
Qed.
Lemma wt_transl_instr:
forall instr k,
+ In instr f.(Linear.fn_code) ->
Lineartyping.wt_instr f instr ->
wt_instrs k ->
wt_instrs (transl_instr fe instr k).
Proof.
- intros. destruct instr; unfold transl_instr; inversion H.
+ intros.
+ generalize (instr_is_within_bounds f instr H H0); intro BND.
+ destruct instr; unfold transl_instr; inv H0; simpl in BND.
(* getstack *)
- destruct s; simpl in H3; apply wt_instrs_cons; auto;
+ destruct BND.
+ destruct s; simpl in *; apply wt_instrs_cons; auto;
constructor; auto.
(* setstack *)
- destruct s; simpl in H3; simpl in H4.
- apply wt_instrs_cons; auto. apply wt_Msetstack'. auto.
- apply index_local_valid. auto.
+ destruct s.
+ apply wt_instrs_cons; auto. apply wt_Msetstack. auto.
auto.
- apply wt_instrs_cons; auto. apply wt_Msetstack'. auto.
- apply index_arg_valid. auto.
+ apply wt_instrs_cons; auto. apply wt_Msetstack. auto.
(* op, move *)
simpl. apply wt_instrs_cons. constructor; auto. auto.
- (* op, undef *)
- simpl. apply wt_instrs_cons. constructor. auto.
(* op, others *)
apply wt_instrs_cons; auto.
constructor.
destruct o; simpl; congruence.
- destruct o; simpl; congruence.
rewrite H6. destruct o; reflexivity || congruence.
(* load *)
apply wt_instrs_cons; auto.
@@ -162,10 +155,14 @@ Proof.
(* store *)
apply wt_instrs_cons; auto.
constructor; auto.
- rewrite H3. destruct a; reflexivity.
+ rewrite H4. destruct a; reflexivity.
(* call *)
apply wt_instrs_cons; auto.
constructor; auto.
+ (* tailcall *)
+ apply wt_restore_callee_save. apply wt_instrs_cons; auto.
+ constructor; auto.
+ destruct s0; auto. rewrite H5; auto.
(* alloc *)
apply wt_instrs_cons; auto. constructor.
(* label *)
@@ -185,7 +182,7 @@ End TRANSL_FUNCTION.
Lemma wt_transf_function:
forall f tf,
- transf_function f = Some tf ->
+ transf_function f = OK tf ->
Lineartyping.wt_function f ->
wt_function tf.
Proof.
@@ -201,7 +198,7 @@ Proof.
constructor.
change (wt_instrs (fn_code tf)).
rewrite H1; simpl; unfold transl_body.
- apply wt_save_callee_save with tf; auto.
+ apply wt_save_callee_save; auto.
unfold transl_code. apply wt_fold_right.
intros. eapply wt_transl_instr; eauto.
red; intros. elim H3.
@@ -213,20 +210,20 @@ Qed.
Lemma wt_transf_fundef:
forall f tf,
Lineartyping.wt_fundef f ->
- transf_fundef f = Some tf ->
+ transf_fundef f = OK tf ->
wt_fundef tf.
Proof.
intros f tf WT. inversion WT; subst.
simpl; intros; inversion H. constructor.
unfold transf_fundef, transf_partial_fundef.
- caseEq (transf_function f0); try congruence.
+ caseEq (transf_function f0); simpl; try congruence.
intros tfn TRANSF EQ. inversion EQ; subst tf.
constructor; eapply wt_transf_function; eauto.
Qed.
Lemma program_typing_preserved:
forall (p: Linear.program) (tp: Mach.program),
- transf_program p = Some tp ->
+ transf_program p = OK tp ->
Lineartyping.wt_program p ->
Machtyping.wt_program tp.
Proof.
diff --git a/backend/Tunneling.v b/backend/Tunneling.v
index 4fbdc9f..15f4676 100644
--- a/backend/Tunneling.v
+++ b/backend/Tunneling.v
@@ -30,8 +30,8 @@ Require Import LTL.
dead code (as the "goto L3" in the example above).
*)
-Definition is_goto_block (b: option block) : option node :=
- match b with Some (Bgoto s) => Some s | _ => None end.
+Definition is_goto_instr (b: option instruction) : option node :=
+ match b with Some (Lnop s) => Some s | _ => None end.
(** [branch_target f pc] returns the node of the CFG that is at
the end of the branch sequence starting at [pc]. If the instruction
@@ -70,7 +70,7 @@ Fixpoint branch_target_rec (f: LTL.function) (pc: node) (count: nat)
match count with
| Datatypes.O => None
| Datatypes.S count' =>
- match is_goto_block f.(fn_code)!pc with
+ match is_goto_instr f.(fn_code)!pc with
| Some s => branch_target_rec f s count'
| None => Some pc
end
@@ -86,34 +86,32 @@ Definition branch_target (f: LTL.function) (pc: node) :=
replacing the destinations of the [Bgoto] and [Bcond] instructions
with their final target, as computed by [branch_target]. *)
-Fixpoint tunnel_block (f: LTL.function) (b: block) {struct b} : block :=
+Definition tunnel_instr (f: LTL.function) (b: instruction) : instruction :=
match b with
- | Bgetstack s r b =>
- Bgetstack s r (tunnel_block f b)
- | Bsetstack r s b =>
- Bsetstack r s (tunnel_block f b)
- | Bop op args res b =>
- Bop op args res (tunnel_block f b)
- | Bload chunk addr args dst b =>
- Bload chunk addr args dst (tunnel_block f b)
- | Bstore chunk addr args src b =>
- Bstore chunk addr args src (tunnel_block f b)
- | Bcall sig ros b =>
- Bcall sig ros (tunnel_block f b)
- | Balloc b =>
- Balloc (tunnel_block f b)
- | Bgoto s =>
- Bgoto (branch_target f s)
- | Bcond cond args s1 s2 =>
- Bcond cond args (branch_target f s1) (branch_target f s2)
- | Breturn =>
- Breturn
+ | Lnop s =>
+ Lnop (branch_target f s)
+ | Lop op args res s =>
+ Lop op args res (branch_target f s)
+ | Lload chunk addr args dst s =>
+ Lload chunk addr args dst (branch_target f s)
+ | Lstore chunk addr args src s =>
+ Lstore chunk addr args src (branch_target f s)
+ | Lcall sig ros args res s =>
+ Lcall sig ros args res (branch_target f s)
+ | Ltailcall sig ros args =>
+ Ltailcall sig ros args
+ | Lalloc arg res s =>
+ Lalloc arg res (branch_target f s)
+ | Lcond cond args s1 s2 =>
+ Lcond cond args (branch_target f s1) (branch_target f s2)
+ | Lreturn or =>
+ Lreturn or
end.
Lemma wf_tunneled_code:
forall (f: LTL.function),
- let tc := PTree.map (fun pc b => tunnel_block f b) (fn_code f) in
- forall (pc: node), Plt pc (Psucc (fn_entrypoint f)) \/ tc!pc = None.
+ let tc := PTree.map (fun pc b => tunnel_instr f b) (fn_code f) in
+ forall (pc: node), Plt pc (fn_nextpc f) \/ tc!pc = None.
Proof.
intros. elim (fn_code_wf f pc); intro.
left; auto. right; unfold tc.
@@ -123,9 +121,11 @@ Qed.
Definition tunnel_function (f: LTL.function) : LTL.function :=
mkfunction
(fn_sig f)
+ (fn_params f)
(fn_stacksize f)
- (PTree.map (fun pc b => tunnel_block f b) (fn_code f))
- (fn_entrypoint f)
+ (PTree.map (fun pc b => tunnel_instr f b) (fn_code f))
+ (branch_target f (fn_entrypoint f))
+ (fn_nextpc f)
(wf_tunneled_code f).
Definition tunnel_fundef (f: LTL.fundef) : LTL.fundef :=
diff --git a/backend/Tunnelingproof.v b/backend/Tunnelingproof.v
index eae53ca..3777eaa 100644
--- a/backend/Tunnelingproof.v
+++ b/backend/Tunnelingproof.v
@@ -7,6 +7,7 @@ Require Import Values.
Require Import Mem.
Require Import Events.
Require Import Globalenvs.
+Require Import Smallstep.
Require Import Op.
Require Import Locations.
Require Import LTL.
@@ -14,51 +15,85 @@ Require Import Tunneling.
(** * Properties of branch target computation *)
-Lemma is_goto_block_correct:
+Lemma is_goto_instr_correct:
forall b s,
- is_goto_block b = Some s -> b = Some (Bgoto s).
+ is_goto_instr b = Some s -> b = Some (Lnop s).
Proof.
- unfold is_goto_block; intros.
- destruct b. destruct b; discriminate || congruence.
- discriminate.
+ unfold is_goto_instr; intros.
+ destruct b; try discriminate.
+ destruct i; discriminate || congruence.
Qed.
Lemma branch_target_rec_1:
forall f pc n,
branch_target_rec f pc n = Some pc
\/ branch_target_rec f pc n = None
- \/ exists pc', f.(fn_code)!pc = Some(Bgoto pc').
+ \/ exists pc', f.(fn_code)!pc = Some(Lnop pc').
Proof.
intros. destruct n; simpl.
right; left; auto.
- caseEq (is_goto_block f.(fn_code)!pc); intros.
- right; right. exists n0. apply is_goto_block_correct; auto.
+ caseEq (is_goto_instr f.(fn_code)!pc); intros.
+ right; right. exists n0. apply is_goto_instr_correct; auto.
left; auto.
Qed.
Lemma branch_target_rec_2:
forall f n pc1 pc2 pc3,
- f.(fn_code)!pc1 = Some (Bgoto pc2) ->
+ f.(fn_code)!pc1 = Some (Lnop pc2) ->
branch_target_rec f pc1 n = Some pc3 ->
branch_target_rec f pc2 n = Some pc3.
Proof.
induction n.
simpl. intros; discriminate.
intros pc1 pc2 pc3 ATpc1 H. simpl in H.
- unfold is_goto_block in H; rewrite ATpc1 in H.
- simpl. caseEq (is_goto_block f.(fn_code)!pc2); intros.
- apply IHn with pc2. apply is_goto_block_correct; auto. auto.
+ unfold is_goto_instr in H; rewrite ATpc1 in H.
+ simpl. caseEq (is_goto_instr f.(fn_code)!pc2); intros.
+ apply IHn with pc2. apply is_goto_instr_correct; auto. auto.
destruct n; simpl in H. discriminate. rewrite H0 in H. auto.
Qed.
+(** Counting the number of consecutive gotos. *)
+
+Fixpoint count_goto_rec (f: LTL.function) (pc: node) (count: nat)
+ {struct count} : nat :=
+ match count with
+ | Datatypes.O => Datatypes.O
+ | Datatypes.S count' =>
+ match is_goto_instr f.(fn_code)!pc with
+ | Some s => Datatypes.S (count_goto_rec f s count')
+ | None => Datatypes.O
+ end
+ end.
+
+Definition count_goto (f: LTL.function) (pc: node) : nat :=
+ count_goto_rec f pc 10%nat.
+
+Lemma count_goto_rec_prop:
+ forall f n pc1 pc2 pc3,
+ f.(fn_code)!pc1 = Some (Lnop pc2) ->
+ branch_target_rec f pc1 n = Some pc3 ->
+ (count_goto_rec f pc2 n < count_goto_rec f pc1 n)%nat.
+Proof.
+ induction n.
+ simpl; intros. discriminate.
+ intros pc1 pc2 pc3 ATpc1 H. simpl in H.
+ unfold is_goto_instr in H; rewrite ATpc1 in H.
+ simpl. unfold is_goto_instr at 2. rewrite ATpc1.
+ caseEq (is_goto_instr f.(fn_code)!pc2); intros.
+ exploit (IHn pc2); eauto. apply is_goto_instr_correct; eauto.
+ omega.
+ omega.
+Qed.
+
(** The following lemma captures the property of [branch_target]
on which the proof of semantic preservation relies. *)
Lemma branch_target_characterization:
forall f pc,
branch_target f pc = pc \/
- (exists pc', f.(fn_code)!pc = Some(Bgoto pc')
- /\ branch_target f pc' = branch_target f pc).
+ (exists pc', f.(fn_code)!pc = Some(Lnop pc')
+ /\ branch_target f pc' = branch_target f pc
+ /\ count_goto f pc' < count_goto f pc)%nat.
Proof.
intros. unfold branch_target.
generalize (branch_target_rec_1 f pc 10%nat).
@@ -67,7 +102,8 @@ Proof.
rewrite A. left; auto.
caseEq (branch_target_rec f pc 10%nat). intros pcx BT.
right. exists pc'. split. auto.
- rewrite (branch_target_rec_2 _ _ _ _ _ AT BT). auto.
+ split. rewrite (branch_target_rec_2 _ _ _ _ _ AT BT). auto.
+ unfold count_goto. eapply count_goto_rec_prop; eauto.
intro. left; auto.
Qed.
@@ -103,221 +139,233 @@ Proof.
destruct f; reflexivity.
Qed.
-(** These are inversion lemmas, characterizing what happens in the LTL
- semantics when executing [Bgoto] instructions or basic blocks. *)
-
-Lemma exec_instrs_Bgoto_inv:
- forall sp b1 ls1 m1 t b2 ls2 m2,
- exec_instrs ge sp b1 ls1 m1 t b2 ls2 m2 ->
- forall s1,
- b1 = Bgoto s1 -> t = E0 /\ b2 = b1 /\ ls2 = ls1 /\ m2 = m1.
+Lemma find_function_translated:
+ forall ros ls f,
+ find_function ge ros ls = Some f ->
+ find_function tge ros ls = Some (tunnel_fundef f).
Proof.
- induction 1.
- intros. tauto.
- intros. subst b1. inversion H.
- intros. generalize (IHexec_instrs1 s1 H2). intros [A [B [C D]]].
- subst t1 b2 rs2 m2.
- generalize (IHexec_instrs2 s1 H2). intros [A [B [C D]]].
- subst t2 b3 rs3 m3. intuition. traceEq.
+ intros until f. destruct ros; simpl.
+ intro. apply functions_translated; auto.
+ rewrite symbols_preserved. destruct (Genv.find_symbol ge i).
+ apply function_ptr_translated; auto.
+ congruence.
Qed.
-Lemma exec_block_Bgoto_inv:
- forall sp s ls1 m1 t out ls2 m2,
- exec_block ge sp (Bgoto s) ls1 m1 t out ls2 m2 ->
- t = E0 /\ out = Cont s /\ ls2 = ls1 /\ m2 = m1.
-Proof.
- intros. inversion H;
- generalize (exec_instrs_Bgoto_inv _ _ _ _ _ _ _ _ H0 s (refl_equal _));
- intros [A [B [C D]]];
- try discriminate.
- intuition congruence.
-Qed.
+(** The proof of semantic preservation is a simulation argument
+ based on diagrams of the following form:
+<<
+ st1 --------------- st2
+ | |
+ t| ?|t
+ | |
+ v v
+ st1'--------------- st2'
+>>
+ The [match_states] predicate, defined below, captures the precondition
+ between states [st1] and [st2], as well as the postcondition between
+ [st1'] and [st2']. One transition in the source code (left) can correspond
+ to zero or one transition in the transformed code (right). The
+ "zero transition" case occurs when executing a [Lgoto] instruction
+ in the source code that has been removed by tunneling.
+
+ In the definition of [match_states], note that only the control-flow
+ (in particular, the current program point [pc]) is changed:
+ the values of locations and the memory states are identical in the
+ original and transformed codes. *)
-Lemma exec_blocks_Bgoto_inv:
- forall c sp pc1 ls1 m1 t out ls2 m2 s,
- exec_blocks ge c sp pc1 ls1 m1 t out ls2 m2 ->
- c!pc1 = Some (Bgoto s) ->
- (t = E0 /\ out = Cont pc1 /\ ls2 = ls1 /\ m2 = m1)
- \/ exec_blocks ge c sp s ls1 m1 t out ls2 m2.
+Definition tunneled_code (f: function) :=
+ PTree.map (fun pc b => tunnel_instr f b) (fn_code f).
+
+Inductive match_stackframes: stackframe -> stackframe -> Prop :=
+ | match_stackframes_intro:
+ forall res f sp ls0 pc,
+ match_stackframes
+ (Stackframe res f sp ls0 pc)
+ (Stackframe res (tunnel_function f) sp ls0 (branch_target f pc)).
+
+Inductive match_states: state -> state -> Prop :=
+ | match_states_intro:
+ forall s f sp pc ls m ts,
+ list_forall2 match_stackframes s ts ->
+ match_states (State s f sp pc ls m)
+ (State ts (tunnel_function f) sp (branch_target f pc) ls m)
+ | match_states_call:
+ forall s f ls m ts,
+ list_forall2 match_stackframes s ts ->
+ match_states (Callstate s f ls m)
+ (Callstate ts (tunnel_fundef f) ls m)
+ | match_states_return:
+ forall s sig ls m ts,
+ list_forall2 match_stackframes s ts ->
+ match_states (Returnstate s sig ls m)
+ (Returnstate ts sig ls m).
+
+Lemma parent_locset_match:
+ forall s ts, list_forall2 match_stackframes s ts -> parent_locset ts = parent_locset s.
Proof.
- induction 1; intros.
- left; tauto.
- assert (b = Bgoto s). congruence. subst b.
- generalize (exec_block_Bgoto_inv _ _ _ _ _ _ _ _ H0).
- intros [A [B [C D]]]. subst t out rs' m'.
- right. apply exec_blocks_refl.
- elim (IHexec_blocks1 H2).
- intros [A [B [C D]]].
- assert (pc2 = pc1). congruence. subst t1 rs2 m2 pc2.
- replace t with t2. apply IHexec_blocks2; auto. traceEq.
- intro. right.
- eapply exec_blocks_trans; eauto.
+ induction 1; simpl; auto. inv H; auto.
Qed.
-(** The following [exec_*_prop] predicates state the correctness
- of the tunneling transformation: for each LTL execution
- in the original code (of an instruction, a sequence of instructions,
- a basic block, a sequence of basic blocks, etc), there exists
- a similar LTL execution in the tunneled code.
-
- Note that only the control-flow is changed: the values of locations
- and the memory states are identical in the original and transformed
- codes. *)
+(** To preserve non-terminating behaviours, we show that the transformed
+ code cannot take an infinity of "zero transition" cases.
+ We use the following [measure] function over source states,
+ which decreases strictly in the "zero transition" case. *)
-Definition tunnel_outcome (f: function) (out: outcome) :=
- match out with
- | Cont pc => Cont (branch_target f pc)
- | Return => Return
+Definition measure (st: state) : nat :=
+ match st with
+ | State s f sp pc ls m => count_goto f pc
+ | Callstate s f ls m => 0%nat
+ | Returnstate s sig ls m => 0%nat
end.
-Definition exec_instr_prop
- (sp: val) (b1: block) (ls1: locset) (m1: mem) (t: trace)
- (b2: block) (ls2: locset) (m2: mem) : Prop :=
- forall f,
- exec_instr tge sp (tunnel_block f b1) ls1 m1
- t (tunnel_block f b2) ls2 m2.
-
-Definition exec_instrs_prop
- (sp: val) (b1: block) (ls1: locset) (m1: mem) (t: trace)
- (b2: block) (ls2: locset) (m2: mem) : Prop :=
- forall f,
- exec_instrs tge sp (tunnel_block f b1) ls1 m1
- t (tunnel_block f b2) ls2 m2.
-
-Definition exec_block_prop
- (sp: val) (b1: block) (ls1: locset) (m1: mem) (t: trace)
- (out: outcome) (ls2: locset) (m2: mem) : Prop :=
- forall f,
- exec_block tge sp (tunnel_block f b1) ls1 m1
- t (tunnel_outcome f out) ls2 m2.
+Lemma branch_target_identity:
+ forall f pc,
+ match f.(fn_code)!pc with Some(Lnop _) => False | _ => True end ->
+ branch_target f pc = pc.
+Proof.
+ intros.
+ destruct (branch_target_characterization f pc) as [A | [pc' [B C]]].
+ auto. rewrite B in H. contradiction.
+Qed.
+
+Lemma tunnel_function_lookup:
+ forall f pc i,
+ f.(fn_code)!pc = Some i ->
+ (tunnel_function f).(fn_code)!pc = Some (tunnel_instr f i).
+Proof.
+ intros. simpl. rewrite PTree.gmap. rewrite H. auto.
+Qed.
-Definition tunneled_code (f: function) :=
- PTree.map (fun pc b => tunnel_block f b) (fn_code f).
-
-Definition exec_blocks_prop
- (c: code) (sp: val)
- (pc: node) (ls1: locset) (m1: mem) (t: trace)
- (out: outcome) (ls2: locset) (m2: mem) : Prop :=
- forall f,
- f.(fn_code) = c ->
- exec_blocks tge (tunneled_code f) sp
- (branch_target f pc) ls1 m1
- t (tunnel_outcome f out) ls2 m2.
-
-Definition exec_function_prop
- (f: fundef) (ls1: locset) (m1: mem) (t: trace)
- (ls2: locset) (m2: mem) : Prop :=
- exec_function tge (tunnel_fundef f) ls1 m1 t ls2 m2.
-
-Scheme exec_instr_ind5 := Minimality for LTL.exec_instr Sort Prop
- with exec_instrs_ind5 := Minimality for LTL.exec_instrs Sort Prop
- with exec_block_ind5 := Minimality for LTL.exec_block Sort Prop
- with exec_blocks_ind5 := Minimality for LTL.exec_blocks Sort Prop
- with exec_function_ind5 := Minimality for LTL.exec_function Sort Prop.
-
-(** The proof of semantic preservation is a structural induction
- over the LTL evaluation derivation of the original program,
- using the [exec_*_prop] predicates above as induction hypotheses. *)
-
-Lemma tunnel_function_correct:
- forall f ls1 m1 t ls2 m2,
- exec_function ge f ls1 m1 t ls2 m2 ->
- exec_function_prop f ls1 m1 t ls2 m2.
+Lemma tunnel_step_correct:
+ forall st1 t st2, step ge st1 t st2 ->
+ forall st1' (MS: match_states st1 st1'),
+ (exists st2', step tge st1' t st2' /\ match_states st2 st2')
+ \/ (measure st2 < measure st1 /\ t = E0 /\ match_states st2 st1')%nat.
Proof.
- apply (exec_function_ind5 ge
- exec_instr_prop
- exec_instrs_prop
- exec_block_prop
- exec_blocks_prop
- exec_function_prop);
- intros; red; intros; simpl.
- (* getstack *)
- constructor.
- (* setstack *)
- constructor.
- (* op *)
- constructor. rewrite <- H. apply eval_operation_preserved.
- exact symbols_preserved.
- (* load *)
- apply exec_Bload with a. rewrite <- H.
- apply eval_addressing_preserved. exact symbols_preserved.
- auto.
- (* store *)
- apply exec_Bstore with a. rewrite <- H.
- apply eval_addressing_preserved. exact symbols_preserved.
- auto.
- (* call *)
- apply exec_Bcall with (tunnel_fundef f).
- generalize H; unfold find_function; destruct ros.
- intro. apply functions_translated; auto.
- rewrite symbols_preserved. destruct (Genv.find_symbol ge i).
- intro. apply function_ptr_translated; auto. congruence.
- generalize (sig_preserved f). congruence.
- apply H2.
- (* alloc *)
- eapply exec_Balloc; eauto.
- (* instr_refl *)
- apply exec_refl.
- (* instr_one *)
- apply exec_one. apply H0.
- (* instr_trans *)
- apply exec_trans with t1 (tunnel_block f b2) rs2 m2 t2; auto.
- (* goto *)
- apply exec_Bgoto. red in H0. simpl in H0. apply H0.
- (* cond, true *)
- eapply exec_Bcond_true. red in H0. simpl in H0. apply H0. auto.
- (* cond, false *)
- eapply exec_Bcond_false. red in H0. simpl in H0. apply H0. auto.
+ induction 1; intros; try inv MS.
+ (* Lnop *)
+ destruct (branch_target_characterization f pc) as [A | [pc1 [B [C D]]]].
+ left; econstructor; split.
+ eapply exec_Lnop. rewrite A.
+ rewrite (tunnel_function_lookup _ _ _ H); simpl; auto.
+ econstructor; eauto.
+ assert (pc1 = pc') by congruence. subst pc1.
+ right. split. simpl. auto. split. auto.
+ rewrite <- C. econstructor; eauto.
+ (* Lop *)
+ rewrite (branch_target_identity f pc); [idtac | rewrite H; auto].
+ left; econstructor; split.
+ eapply exec_Lop with (v := v); eauto.
+ rewrite (tunnel_function_lookup _ _ _ H); simpl; auto.
+ rewrite <- H0. apply eval_operation_preserved. exact symbols_preserved.
+ econstructor; eauto.
+ (* Lload *)
+ rewrite (branch_target_identity f pc); [idtac | rewrite H; auto].
+ left; econstructor; split.
+ eapply exec_Lload; eauto.
+ rewrite (tunnel_function_lookup _ _ _ H); simpl; auto.
+ rewrite <- H0. apply eval_addressing_preserved. exact symbols_preserved.
+ econstructor; eauto.
+ (* Lstore *)
+ rewrite (branch_target_identity f pc); [idtac | rewrite H; auto].
+ left; econstructor; split.
+ eapply exec_Lstore; eauto.
+ rewrite (tunnel_function_lookup _ _ _ H); simpl; auto.
+ rewrite <- H0. apply eval_addressing_preserved. exact symbols_preserved.
+ econstructor; eauto.
+ (* Lcall *)
+ unfold rs1. inv MS.
+ left; econstructor; split.
+ eapply exec_Lcall with (f' := tunnel_fundef f'); eauto.
+ rewrite (branch_target_identity f pc); [idtac | rewrite H; auto].
+ rewrite (tunnel_function_lookup _ _ _ H); simpl.
+ rewrite sig_preserved. auto.
+ apply find_function_translated; auto.
+ rewrite sig_preserved; auto. fold rs1.
+ econstructor; eauto.
+ constructor; auto.
+ constructor; auto.
+ (* Ltailcall *)
+ unfold rs2, rs1 in *. inv MS. fold rs1. fold rs2.
+ left; econstructor; split.
+ eapply exec_Ltailcall with (f' := tunnel_fundef f'); eauto.
+ rewrite (branch_target_identity f pc); [idtac | rewrite H; auto].
+ rewrite (tunnel_function_lookup _ _ _ H); simpl.
+ rewrite sig_preserved. auto.
+ apply find_function_translated; auto.
+ rewrite sig_preserved; auto. fold rs1.
+ rewrite (parent_locset_match _ _ H9).
+ econstructor; eauto.
+ (* Lalloc *)
+ rewrite (branch_target_identity f pc); [idtac | rewrite H; auto].
+ left; exists (State ts (tunnel_function f) sp (branch_target f pc') rs3 m'); split.
+ unfold rs3, rs2, rs1; eapply exec_Lalloc; eauto.
+ rewrite (tunnel_function_lookup _ _ _ H); simpl; auto.
+ econstructor; eauto.
+ (* cond *)
+ rewrite (branch_target_identity f pc); [idtac | rewrite H; auto].
+ left; econstructor; split.
+ eapply exec_Lcond_true; eauto.
+ rewrite (tunnel_function_lookup _ _ _ H); simpl; eauto.
+ econstructor; eauto.
+ rewrite (branch_target_identity f pc); [idtac | rewrite H; auto].
+ left; econstructor; split.
+ eapply exec_Lcond_false; eauto.
+ rewrite (tunnel_function_lookup _ _ _ H); simpl; eauto.
+ econstructor; eauto.
(* return *)
- apply exec_Breturn. red in H0. simpl in H0. apply H0.
- (* block_refl *)
- apply exec_blocks_refl.
- (* block_one *)
- red in H1.
- elim (branch_target_characterization f pc).
- intro. rewrite H3. apply exec_blocks_one with (tunnel_block f b).
- unfold tunneled_code. rewrite PTree.gmap. rewrite H2; rewrite H.
- reflexivity. apply H1.
- intros [pc' [ATpc BTS]].
- assert (b = Bgoto pc'). congruence. subst b.
- generalize (exec_block_Bgoto_inv _ _ _ _ _ _ _ _ H0).
- intros [A [B [C D]]]. subst t out rs' m'.
- simpl. rewrite BTS. apply exec_blocks_refl.
- (* blocks_trans *)
- apply exec_blocks_trans with t1 (branch_target f pc2) rs2 m2 t2.
- exact (H0 f H4). exact (H2 f H4). auto.
+ rewrite (branch_target_identity f pc); [idtac | rewrite H; auto].
+ left; econstructor; split.
+ eapply exec_Lreturn; eauto.
+ rewrite (tunnel_function_lookup _ _ _ H); simpl; eauto.
+ simpl. rewrite (parent_locset_match _ _ H7). constructor; auto.
(* internal function *)
- econstructor. eexact H.
- change (fn_code (tunnel_function f)) with (tunneled_code f).
- simpl.
- elim (branch_target_characterization f (fn_entrypoint f)).
- intro BT. rewrite <- BT. exact (H1 f (refl_equal _)).
- intros [pc [ATpc BT]].
- apply exec_blocks_trans with
- E0 (branch_target f (fn_entrypoint f)) (call_regs rs) m1 t.
- eapply exec_blocks_one.
- unfold tunneled_code. rewrite PTree.gmap. rewrite ATpc.
- simpl. reflexivity.
- apply exec_Bgoto. rewrite BT. apply exec_refl.
- exact (H1 f (refl_equal _)). traceEq.
+ simpl. left; econstructor; split.
+ eapply exec_function_internal; eauto.
+ simpl. econstructor; eauto.
(* external function *)
- econstructor; eauto.
+ simpl. left; econstructor; split.
+ eapply exec_function_external; eauto.
+ simpl. econstructor; eauto.
+ (* return *)
+ inv H4. inv H1.
+ left; econstructor; split.
+ eapply exec_return; eauto.
+ fold rs1. constructor. auto.
Qed.
-End PRESERVATION.
+Lemma transf_initial_states:
+ forall st1, initial_state p st1 ->
+ exists st2, initial_state tp st2 /\ match_states st1 st2.
+Proof.
+ intros. inversion H.
+ exists (Callstate nil (tunnel_fundef f) (Locmap.init Vundef) (Genv.init_mem tp)); split.
+ econstructor; eauto.
+ change (prog_main tp) with (prog_main p).
+ rewrite symbols_preserved. eauto.
+ apply function_ptr_translated; auto.
+ rewrite <- H2. apply sig_preserved.
+ replace (Genv.init_mem tp) with (Genv.init_mem p).
+ constructor. constructor. auto.
+ symmetry. unfold tp, tunnel_program. apply Genv.init_mem_transf.
+Qed.
+
+Lemma transf_final_states:
+ forall st1 st2 r,
+ match_states st1 st2 -> final_state st1 r -> final_state st2 r.
+Proof.
+ intros. inv H0. inv H. inv H6. constructor. auto.
+Qed.
Theorem transf_program_correct:
- forall (p: program) (t: trace) (r: val),
- exec_program p t r ->
- exec_program (tunnel_program p) t r.
+ forall (beh: program_behavior),
+ exec_program p beh -> exec_program tp beh.
Proof.
- intros p t r [b [f [ls [m [FIND1 [FIND2 [SIG [EX RES]]]]]]]].
- red. exists b; exists (tunnel_fundef f); exists ls; exists m.
- split. change (prog_main (tunnel_program p)) with (prog_main p).
- rewrite <- FIND1. apply symbols_preserved.
- split. apply function_ptr_translated. assumption.
- split. generalize (sig_preserved f). congruence.
- split. apply tunnel_function_correct.
- unfold tunnel_program. rewrite Genv.init_mem_transf. auto.
- rewrite sig_preserved. exact RES.
+ unfold exec_program; intros.
+ eapply simulation_opt_preservation; eauto.
+ eexact transf_initial_states.
+ eexact transf_final_states.
+ eexact tunnel_step_correct.
Qed.
+
+End PRESERVATION.
diff --git a/backend/Tunnelingtyping.v b/backend/Tunnelingtyping.v
index 6281afa..c611067 100644
--- a/backend/Tunnelingtyping.v
+++ b/backend/Tunnelingtyping.v
@@ -11,26 +11,65 @@ Require Import Locations.
Require Import LTL.
Require Import LTLtyping.
Require Import Tunneling.
+Require Import Tunnelingproof.
(** Tunneling preserves typing. *)
-Lemma wt_tunnel_block:
- forall f b,
- wt_block f b ->
- wt_block (tunnel_function f) (tunnel_block f b).
+Lemma branch_target_rec_valid:
+ forall f, wt_function f ->
+ forall count pc pc',
+ branch_target_rec f pc count = Some pc' ->
+ valid_successor f pc ->
+ valid_successor f pc'.
Proof.
- induction 1; simpl; econstructor; eauto.
+ induction count; simpl.
+ intros; discriminate.
+ intros until pc'. caseEq (is_goto_instr (fn_code f)!pc); intros.
+ generalize (is_goto_instr_correct _ _ H0). intro.
+ eapply IHcount; eauto.
+ generalize (wt_instrs _ H _ _ H3); intro WTI; inv WTI. auto.
+ inv H1; auto.
+Qed.
+
+Lemma tunnel_valid_successor:
+ forall f pc,
+ valid_successor f pc -> valid_successor (tunnel_function f) pc.
+Proof.
+ intros. destruct H as [i AT].
+ unfold valid_successor; simpl. rewrite PTree.gmap. rewrite AT.
+ simpl. exists (tunnel_instr f i); auto.
+Qed.
+
+Lemma branch_target_valid:
+ forall f pc,
+ wt_function f ->
+ valid_successor f pc ->
+ valid_successor (tunnel_function f) (branch_target f pc).
+Proof.
+ intros. apply tunnel_valid_successor.
+ unfold branch_target. caseEq (branch_target_rec f pc 10); intros.
+ eapply branch_target_rec_valid; eauto.
+ auto.
+Qed.
+
+Lemma wt_tunnel_instr:
+ forall f i,
+ wt_function f ->
+ wt_instr f i -> wt_instr (tunnel_function f) (tunnel_instr f i).
+Proof.
+ intros; inv H0; simpl; econstructor; eauto;
+ eapply branch_target_valid; eauto.
Qed.
Lemma wt_tunnel_function:
forall f, wt_function f -> wt_function (tunnel_function f).
Proof.
- unfold wt_function; intros until b.
- simpl. rewrite PTree.gmap. unfold option_map.
- caseEq (fn_code f)!pc. intros b0 AT EQ.
- injection EQ; intros; subst b.
- apply wt_tunnel_block. eauto.
- intros; discriminate.
+ intros. inversion H. constructor; simpl; auto.
+ intros until instr. rewrite PTree.gmap. unfold option_map.
+ caseEq (fn_code f)!pc. intros b0 AT EQ. inv EQ.
+ apply wt_tunnel_instr; eauto.
+ congruence.
+ eapply branch_target_valid; eauto.
Qed.
Lemma wt_tunnel_fundef:
diff --git a/caml/CMlexer.mll b/caml/CMlexer.mll
index 49d0dbd..ae71e0c 100644
--- a/caml/CMlexer.mll
+++ b/caml/CMlexer.mll
@@ -30,8 +30,10 @@ rule token = parse
| "|" { BAR }
| "||" { BARBAR }
| "^" { CARET }
+ | "case" { CASE }
| ":" { COLON }
| "," { COMMA }
+ | "default" { DEFAULT }
| "$" { DOLLAR }
| "else" { ELSE }
| "=" { EQUAL }
@@ -75,6 +77,7 @@ rule token = parse
| "let" { LET }
| "loop" { LOOP }
| "(" { LPAREN }
+ | "match" { MATCH }
| "-" { MINUS }
| "->" { MINUSGREATER }
| "-f" { MINUSF }
diff --git a/caml/CMparser.mly b/caml/CMparser.mly
index d9a8187..0db0af2 100644
--- a/caml/CMparser.mly
+++ b/caml/CMparser.mly
@@ -8,16 +8,67 @@ open BinPos
open BinInt
open Integers
open AST
-open Op
open Cminor
let intconst n =
- Eop(Ointconst(coqint_of_camlint n), Enil)
+ Econst(Ointconst(coqint_of_camlint n))
let andbool e1 e2 =
- Cmconstr.conditionalexpr e1 e2 (intconst 0l)
+ Econdition(e1, e2, intconst 0l)
let orbool e1 e2 =
- Cmconstr.conditionalexpr e1 (intconst 1l) e2
+ Econdition(e1, intconst 1l, e2)
+
+let exitnum n = nat_of_camlint(Int32.pred n)
+
+let mkswitch expr (cases, dfl) =
+ let rec mktable = function
+ | [] -> Coq_nil
+ | (key, exit) :: rem ->
+ Coq_cons(Coq_pair(coqint_of_camlint key, exitnum exit), mktable rem) in
+ Sswitch(expr, mktable cases, exitnum dfl)
+
+(***
+ match (a) { case 0: s0; case 1: s1; case 2: s2; } --->
+
+ block {
+ block {
+ block {
+ block {
+ switch(a) { case 0: exit 0; case 1: exit 1; default: exit 2; }
+ }; s0; exit 2;
+ }; s1; exit 1;
+ }; s2;
+ }
+
+ Note that matches are assumed to be exhaustive
+***)
+
+let mkmatch_aux expr cases =
+ let ncases = Int32.of_int (List.length cases) in
+ let rec mktable n = function
+ | [] -> assert false
+ | [key, action] -> Coq_nil
+ | (key, action) :: rem ->
+ Coq_cons(Coq_pair(coqint_of_camlint key, nat_of_camlint n),
+ mktable (Int32.succ n) rem) in
+ let sw =
+ Sswitch(expr, mktable 0l cases, nat_of_camlint (Int32.pred ncases)) in
+ let rec mkblocks body n = function
+ | [] -> assert false
+ | [key, action] ->
+ Sblock(Sseq(body, action))
+ | (key, action) :: rem ->
+ mkblocks
+ (Sblock(Sseq(body, Sseq(action, Sexit (nat_of_camlint n)))))
+ (Int32.pred n)
+ rem in
+ mkblocks (Sblock sw) (Int32.pred ncases) cases
+
+let mkmatch expr cases =
+ match cases with
+ | [] -> Sskip (* ??? *)
+ | [key, action] -> action
+ | _ -> mkmatch_aux expr cases
%}
@@ -32,8 +83,10 @@ let orbool e1 e2 =
%token BAR
%token BARBAR
%token CARET
+%token CASE
%token COLON
%token COMMA
+%token DEFAULT
%token DOLLAR
%token ELSE
%token EQUAL
@@ -81,6 +134,7 @@ let orbool e1 e2 =
%token LET
%token LOOP
%token LPAREN
+%token MATCH
%token MINUS
%token MINUSF
%token MINUSGREATER
@@ -200,7 +254,7 @@ parameter_list:
stack_declaration:
/* empty */ { Z0 }
- | STACK INTLIT { z_of_camlint $2 }
+ | STACK INTLIT SEMICOLON { z_of_camlint $2 }
;
var_declarations:
@@ -217,14 +271,18 @@ var_declaration:
stmt:
expr SEMICOLON { Sexpr $1 }
| IDENT EQUAL expr SEMICOLON { Sassign($1, $3) }
- | IF LPAREN expr RPAREN stmts ELSE stmts { Cmconstr.ifthenelse $3 $5 $7 }
- | IF LPAREN expr RPAREN stmts { Cmconstr.ifthenelse $3 $5 Sskip }
+ | IF LPAREN expr RPAREN stmts ELSE stmts { Sifthenelse($3, $5, $7) }
+ | IF LPAREN expr RPAREN stmts { Sifthenelse($3, $5, Sskip) }
| LOOP stmts { Sloop($2) }
| LBRACELBRACE stmt_list RBRACERBRACE { Sblock($2) }
| EXIT SEMICOLON { Sexit O }
- | EXIT INTLIT SEMICOLON { Sexit (nat_of_camlint(Int32.pred $2)) }
+ | EXIT INTLIT SEMICOLON { Sexit (exitnum $2) }
| RETURN SEMICOLON { Sreturn None }
| RETURN expr SEMICOLON { Sreturn (Some $2) }
+ | SWITCH LPAREN expr RPAREN LBRACE switch_cases RBRACE
+ { mkswitch $3 $6 }
+ | MATCH LPAREN expr RPAREN LBRACE match_cases RBRACE
+ { mkmatch $3 $6 }
;
stmts:
@@ -237,72 +295,84 @@ stmt_list:
| stmt stmt_list { Sseq($1, $2) }
;
+switch_cases:
+ DEFAULT COLON EXIT INTLIT SEMICOLON
+ { ([], $4) }
+ | CASE INTLIT COLON EXIT INTLIT SEMICOLON switch_cases
+ { let (cases, dfl) = $7 in (($2, $5) :: cases, dfl) }
+;
+
+match_cases:
+ /* empty */ { [] }
+ | CASE INTLIT COLON stmt_list match_cases { ($2, $4) :: $5 }
+;
+
/* Expressions */
expr:
LPAREN expr RPAREN { $2 }
| IDENT { Evar $1 }
| INTLIT { intconst $1 }
- | FLOATLIT { Eop(Ofloatconst $1, Enil) }
- | STRINGLIT { Eop(Oaddrsymbol($1, Int.zero), Enil) }
- | AMPERSAND INTLIT { Eop(Oaddrstack(coqint_of_camlint $2), Enil) }
- | MINUS expr %prec p_uminus { Cmconstr.negint $2 }
- | MINUSF expr %prec p_uminus { Cmconstr.negfloat $2 }
- | ABSF expr { Cmconstr.absfloat $2 }
- | INTOFFLOAT expr { Cmconstr.intoffloat $2 }
- | FLOATOFINT expr { Cmconstr.floatofint $2 }
- | FLOATOFINTU expr { Cmconstr.floatofintu $2 }
- | TILDE expr { Cmconstr.notint $2 }
- | BANG expr { Cmconstr.notbool $2 }
- | INT8S expr { Cmconstr.cast8signed $2 }
- | INT8U expr { Cmconstr.cast8unsigned $2 }
- | INT16S expr { Cmconstr.cast16signed $2 }
- | INT16U expr { Cmconstr.cast16unsigned $2 }
- | FLOAT32 expr { Cmconstr.singleoffloat $2 }
+ | FLOATLIT { Econst(Ofloatconst $1) }
+ | STRINGLIT { Econst(Oaddrsymbol($1, Int.zero)) }
+ | AMPERSAND INTLIT { Econst(Oaddrstack(coqint_of_camlint $2)) }
+ | MINUS expr %prec p_uminus { Eunop(Onegint, $2) }
+ | MINUSF expr %prec p_uminus { Eunop(Onegf, $2) }
+ | ABSF expr { Eunop(Oabsf, $2) }
+ | INTOFFLOAT expr { Eunop(Ointoffloat, $2) }
+ | FLOATOFINT expr { Eunop(Ofloatofint, $2) }
+ | FLOATOFINTU expr { Eunop(Ofloatofintu, $2) }
+ | TILDE expr { Eunop(Onotint, $2) }
+ | BANG expr { Eunop(Onotbool, $2) }
+ | INT8S expr { Eunop(Ocast8signed, $2) }
+ | INT8U expr { Eunop(Ocast8unsigned, $2) }
+ | INT16S expr { Eunop(Ocast16signed, $2) }
+ | INT16U expr { Eunop(Ocast16unsigned, $2) }
+ | FLOAT32 expr { Eunop(Osingleoffloat, $2) }
| ALLOC expr { Ealloc $2 }
- | expr PLUS expr { Cmconstr.add $1 $3 }
- | expr MINUS expr { Cmconstr.sub $1 $3 }
- | expr STAR expr { Cmconstr.mul $1 $3 }
- | expr SLASH expr { Cmconstr.divs $1 $3 }
- | expr PERCENT expr { Cmconstr.mods $1 $3 }
- | expr SLASHU expr { Cmconstr.divu $1 $3 }
- | expr PERCENTU expr { Cmconstr.modu $1 $3 }
- | expr AMPERSAND expr { Cmconstr.coq_and $1 $3 }
- | expr BAR expr { Cmconstr.coq_or $1 $3 }
- | expr CARET expr { Cmconstr.xor $1 $3 }
- | expr LESSLESS expr { Cmconstr.shl $1 $3 }
- | expr GREATERGREATER expr { Cmconstr.shr $1 $3 }
- | expr GREATERGREATERU expr { Cmconstr.shru $1 $3 }
- | expr PLUSF expr { Cmconstr.addf $1 $3 }
- | expr MINUSF expr { Cmconstr.subf $1 $3 }
- | expr STARF expr { Cmconstr.mulf $1 $3 }
- | expr SLASHF expr { Cmconstr.divf $1 $3 }
- | expr EQUALEQUAL expr { Cmconstr.cmp Ceq $1 $3 }
- | expr BANGEQUAL expr { Cmconstr.cmp Cne $1 $3 }
- | expr LESS expr { Cmconstr.cmp Clt $1 $3 }
- | expr LESSEQUAL expr { Cmconstr.cmp Cle $1 $3 }
- | expr GREATER expr { Cmconstr.cmp Cgt $1 $3 }
- | expr GREATEREQUAL expr { Cmconstr.cmp Cge $1 $3 }
- | expr EQUALEQUALU expr { Cmconstr.cmpu Ceq $1 $3 }
- | expr BANGEQUALU expr { Cmconstr.cmpu Cne $1 $3 }
- | expr LESSU expr { Cmconstr.cmpu Clt $1 $3 }
- | expr LESSEQUALU expr { Cmconstr.cmpu Cle $1 $3 }
- | expr GREATERU expr { Cmconstr.cmpu Cgt $1 $3 }
- | expr GREATEREQUALU expr { Cmconstr.cmpu Cge $1 $3 }
- | expr EQUALEQUALF expr { Cmconstr.cmpf Ceq $1 $3 }
- | expr BANGEQUALF expr { Cmconstr.cmpf Cne $1 $3 }
- | expr LESSF expr { Cmconstr.cmpf Clt $1 $3 }
- | expr LESSEQUALF expr { Cmconstr.cmpf Cle $1 $3 }
- | expr GREATERF expr { Cmconstr.cmpf Cgt $1 $3 }
- | expr GREATEREQUALF expr { Cmconstr.cmpf Cge $1 $3 }
- | memory_chunk LBRACKET expr RBRACKET { Cmconstr.load $1 $3 }
+ | expr PLUS expr { Ebinop(Oadd, $1, $3) }
+ | expr MINUS expr { Ebinop(Osub, $1, $3) }
+ | expr STAR expr { Ebinop(Omul, $1, $3) }
+ | expr SLASH expr { Ebinop(Odiv, $1, $3) }
+ | expr PERCENT expr { Ebinop(Omod, $1, $3) }
+ | expr SLASHU expr { Ebinop(Odivu, $1, $3) }
+ | expr PERCENTU expr { Ebinop(Omodu, $1, $3) }
+ | expr AMPERSAND expr { Ebinop(Oand, $1, $3) }
+ | expr BAR expr { Ebinop(Oor, $1, $3) }
+ | expr CARET expr { Ebinop(Oxor, $1, $3) }
+ | expr LESSLESS expr { Ebinop(Oshl, $1, $3) }
+ | expr GREATERGREATER expr { Ebinop(Oshr, $1, $3) }
+ | expr GREATERGREATERU expr { Ebinop(Oshru, $1, $3) }
+ | expr PLUSF expr { Ebinop(Oaddf, $1, $3) }
+ | expr MINUSF expr { Ebinop(Osubf, $1, $3) }
+ | expr STARF expr { Ebinop(Omulf, $1, $3) }
+ | expr SLASHF expr { Ebinop(Odivf, $1, $3) }
+ | expr EQUALEQUAL expr { Ebinop(Ocmp Ceq, $1, $3) }
+ | expr BANGEQUAL expr { Ebinop(Ocmp Cne, $1, $3) }
+ | expr LESS expr { Ebinop(Ocmp Clt, $1, $3) }
+ | expr LESSEQUAL expr { Ebinop(Ocmp Cle, $1, $3) }
+ | expr GREATER expr { Ebinop(Ocmp Cgt, $1, $3) }
+ | expr GREATEREQUAL expr { Ebinop(Ocmp Cge, $1, $3) }
+ | expr EQUALEQUALU expr { Ebinop(Ocmpu Ceq, $1, $3) }
+ | expr BANGEQUALU expr { Ebinop(Ocmpu Cne, $1, $3) }
+ | expr LESSU expr { Ebinop(Ocmpu Clt, $1, $3) }
+ | expr LESSEQUALU expr { Ebinop(Ocmpu Cle, $1, $3) }
+ | expr GREATERU expr { Ebinop(Ocmpu Cgt, $1, $3) }
+ | expr GREATEREQUALU expr { Ebinop(Ocmpu Cge, $1, $3) }
+ | expr EQUALEQUALF expr { Ebinop(Ocmpf Ceq, $1, $3) }
+ | expr BANGEQUALF expr { Ebinop(Ocmpf Cne, $1, $3) }
+ | expr LESSF expr { Ebinop(Ocmpf Clt, $1, $3) }
+ | expr LESSEQUALF expr { Ebinop(Ocmpf Cle, $1, $3) }
+ | expr GREATERF expr { Ebinop(Ocmpf Cgt, $1, $3) }
+ | expr GREATEREQUALF expr { Ebinop(Ocmpf Cge, $1, $3) }
+ | memory_chunk LBRACKET expr RBRACKET { Eload($1, $3) }
| memory_chunk LBRACKET expr RBRACKET EQUAL expr
- { Cmconstr.store $1 $3 $6 }
+ { Estore($1, $3, $6) }
| expr LPAREN expr_list RPAREN COLON signature
{ Ecall($6, $1, $3) }
| expr AMPERSANDAMPERSAND expr { andbool $1 $3 }
| expr BARBAR expr { orbool $1 $3 }
- | expr QUESTION expr COLON expr { Cmconstr.conditionalexpr $1 $3 $5 }
+ | expr QUESTION expr COLON expr { Econdition($1, $3, $5) }
| LET expr IN expr %prec p_let { Elet($2, $4) }
| DOLLAR INTLIT { Eletvar (nat_of_camlint $2) }
;
diff --git a/caml/CMtypecheck.ml b/caml/CMtypecheck.ml
index a926039..495ded0 100644
--- a/caml/CMtypecheck.ml
+++ b/caml/CMtypecheck.ml
@@ -6,7 +6,6 @@ open CList
open Camlcoq
open AST
open Integers
-open Op
open Cminor
exception Error of string
@@ -67,135 +66,91 @@ let name_of_comparison = function
| Cgt -> "gt"
| Cge -> "ge"
-let type_condition = function
- | Ccomp _ -> [tint;tint]
- | Ccompu _ -> [tint;tint]
- | Ccompimm _ -> [tint]
- | Ccompuimm _ -> [tint]
- | Ccompf _ -> [tfloat;tfloat]
- | Cnotcompf _ -> [tfloat;tfloat]
- | Cmaskzero _ -> [tint]
- | Cmasknotzero _ -> [tint]
+let type_constant = function
+ | Ointconst _ -> tint
+ | Ofloatconst _ -> tfloat
+ | Oaddrsymbol _ -> tint
+ | Oaddrstack _ -> tint
-let name_of_condition = function
- | Ccomp c -> sprintf "comp %s" (name_of_comparison c)
- | Ccompu c -> sprintf "compu %s" (name_of_comparison c)
- | Ccompimm(c, n) -> sprintf "compimm %s %ld" (name_of_comparison c) (camlint_of_coqint n)
- | Ccompuimm(c, n) -> sprintf "compuimm %s %ld" (name_of_comparison c) (camlint_of_coqint n)
- | Ccompf c -> sprintf "compf %s" (name_of_comparison c)
- | Cnotcompf c -> sprintf "notcompf %s" (name_of_comparison c)
- | Cmaskzero n -> sprintf "maskzero %ld" (camlint_of_coqint n)
- | Cmasknotzero n -> sprintf "masknotzero %ld" (camlint_of_coqint n)
+let type_unary_operation = function
+ | Ocast8signed -> tint, tint
+ | Ocast16signed -> tint, tint
+ | Ocast8unsigned -> tint, tint
+ | Ocast16unsigned -> tint, tint
+ | Onegint -> tint, tint
+ | Onotbool -> tint, tint
+ | Onotint -> tint, tint
+ | Onegf -> tfloat, tfloat
+ | Oabsf -> tfloat, tfloat
+ | Osingleoffloat -> tfloat, tfloat
+ | Ointoffloat -> tfloat, tint
+ | Ofloatofint -> tint, tfloat
+ | Ofloatofintu -> tint, tfloat
-let type_operation = function
- | Omove -> let v = newvar() in [v], v
- | Ointconst _ -> [], tint
- | Ofloatconst _ -> [], tfloat
- | Oaddrsymbol _ -> [], tint
- | Oaddrstack _ -> [], tint
- | Oundef -> [], newvar()
- | Ocast8signed -> [tint], tint
- | Ocast16signed -> [tint], tint
- | Ocast8unsigned -> [tint], tint
- | Ocast16unsigned -> [tint], tint
- | Oadd -> [tint;tint], tint
- | Oaddimm _ -> [tint], tint
- | Osub -> [tint;tint], tint
- | Osubimm _ -> [tint], tint
- | Omul -> [tint;tint], tint
- | Omulimm _ -> [tint], tint
- | Odiv -> [tint;tint], tint
- | Odivu -> [tint;tint], tint
- | Oand -> [tint;tint], tint
- | Oandimm _ -> [tint], tint
- | Oor -> [tint;tint], tint
- | Oorimm _ -> [tint], tint
- | Oxor -> [tint;tint], tint
- | Oxorimm _ -> [tint], tint
- | Onand -> [tint;tint], tint
- | Onor -> [tint;tint], tint
- | Onxor -> [tint;tint], tint
- | Oshl -> [tint;tint], tint
- | Oshr -> [tint;tint], tint
- | Oshrimm _ -> [tint], tint
- | Oshrximm _ -> [tint], tint
- | Oshru -> [tint;tint], tint
- | Orolm _ -> [tint], tint
- | Onegf -> [tfloat], tfloat
- | Oabsf -> [tfloat], tfloat
- | Oaddf -> [tfloat;tfloat], tfloat
- | Osubf -> [tfloat;tfloat], tfloat
- | Omulf -> [tfloat;tfloat], tfloat
- | Odivf -> [tfloat;tfloat], tfloat
- | Omuladdf -> [tfloat;tfloat;tfloat], tfloat
- | Omulsubf -> [tfloat;tfloat;tfloat], tfloat
- | Osingleoffloat -> [tfloat], tfloat
- | Ointoffloat -> [tfloat], tint
- | Ofloatofint -> [tint], tfloat
- | Ofloatofintu -> [tint], tfloat
- | Ocmp c -> type_condition c, tint
+let type_binary_operation = function
+ | Oadd -> tint, tint, tint
+ | Osub -> tint, tint, tint
+ | Omul -> tint, tint, tint
+ | Odiv -> tint, tint, tint
+ | Odivu -> tint, tint, tint
+ | Omod -> tint, tint, tint
+ | Omodu -> tint, tint, tint
+ | Oand -> tint, tint, tint
+ | Oor -> tint, tint, tint
+ | Oxor -> tint, tint, tint
+ | Oshl -> tint, tint, tint
+ | Oshr -> tint, tint, tint
+ | Oshru -> tint, tint, tint
+ | Oaddf -> tfloat, tfloat, tfloat
+ | Osubf -> tfloat, tfloat, tfloat
+ | Omulf -> tfloat, tfloat, tfloat
+ | Odivf -> tfloat, tfloat, tfloat
+ | Ocmp _ -> tint, tint, tint
+ | Ocmpu _ -> tint, tint, tint
+ | Ocmpf _ -> tfloat, tfloat, tint
-let name_of_operation = function
- | Omove -> "move"
+let name_of_constant = function
| Ointconst n -> sprintf "intconst %ld" (camlint_of_coqint n)
| Ofloatconst n -> sprintf "floatconst %g" n
| Oaddrsymbol (s, ofs) -> sprintf "addrsymbol %s %ld" (extern_atom s) (camlint_of_coqint ofs)
| Oaddrstack n -> sprintf "addrstack %ld" (camlint_of_coqint n)
- | Oundef -> "undef"
+
+let name_of_unary_operation = function
| Ocast8signed -> "cast8signed"
| Ocast16signed -> "cast16signed"
| Ocast8unsigned -> "cast8unsigned"
| Ocast16unsigned -> "cast16unsigned"
+ | Onegint -> "negint"
+ | Onotbool -> "notbool"
+ | Onotint -> "notint"
+ | Onegf -> "negf"
+ | Oabsf -> "absf"
+ | Osingleoffloat -> "singleoffloat"
+ | Ointoffloat -> "intoffloat"
+ | Ofloatofint -> "floatofint"
+ | Ofloatofintu -> "floatofintu"
+
+let name_of_binary_operation = function
| Oadd -> "add"
- | Oaddimm n -> sprintf "addimm %ld" (camlint_of_coqint n)
| Osub -> "sub"
- | Osubimm n -> sprintf "subimm %ld" (camlint_of_coqint n)
| Omul -> "mul"
- | Omulimm n -> sprintf "mulimm %ld" (camlint_of_coqint n)
| Odiv -> "div"
| Odivu -> "divu"
+ | Omod -> "mod"
+ | Omodu -> "modu"
| Oand -> "and"
- | Oandimm n -> sprintf "andimm %ld" (camlint_of_coqint n)
| Oor -> "or"
- | Oorimm n -> sprintf "orimm %ld" (camlint_of_coqint n)
| Oxor -> "xor"
- | Oxorimm n -> sprintf "xorimm %ld" (camlint_of_coqint n)
- | Onand -> "nand"
- | Onor -> "nor"
- | Onxor -> "nxor"
| Oshl -> "shl"
| Oshr -> "shr"
- | Oshrimm n -> sprintf "shrimm %ld" (camlint_of_coqint n)
- | Oshrximm n -> sprintf "shrximm %ld" (camlint_of_coqint n)
| Oshru -> "shru"
- | Orolm(n, m) -> sprintf "rolm %ld %ld" (camlint_of_coqint n) (camlint_of_coqint m)
- | Onegf -> "negf"
- | Oabsf -> "absf"
| Oaddf -> "addf"
| Osubf -> "subf"
| Omulf -> "mulf"
| Odivf -> "divf"
- | Omuladdf -> "muladdf"
- | Omulsubf -> "mulsubf"
- | Osingleoffloat -> "singleoffloat"
- | Ointoffloat -> "intoffloat"
- | Ofloatofint -> "floatofint"
- | Ofloatofintu -> "floatofintu"
- | Ocmp c -> name_of_condition c
-
-let type_addressing = function
- | Aindexed _ -> [tint]
- | Aindexed2 -> [tint;tint]
- | Aglobal _ -> []
- | Abased _ -> [tint]
- | Ainstack _ -> []
-
-let name_of_addressing = function
- | Aindexed n -> sprintf "indexed %ld" (camlint_of_coqint n)
- | Aindexed2 -> sprintf "indexed2"
- | Aglobal(s, ofs) -> sprintf "global %s %ld" (extern_atom s) (camlint_of_coqint ofs)
- | Abased(s, ofs) -> sprintf "based %s %ld" (extern_atom s) (camlint_of_coqint ofs)
- | Ainstack n -> sprintf "instack %ld" (camlint_of_coqint n)
+ | Ocmp c -> sprintf "cmp %s" (name_of_comparison c)
+ | Ocmpu c -> sprintf "cmpu %s" (name_of_comparison c)
+ | Ocmpf c -> sprintf "cmpf %s" (name_of_comparison c)
let type_chunk = function
| Mint8signed -> tint
@@ -219,34 +174,47 @@ let rec type_expr env lenv e =
match e with
| Evar id ->
type_var env id
- | Eop(op, el) ->
- let tel = type_exprlist env lenv el in
- let (targs, tres) = type_operation op in
+ | Econst cst ->
+ type_constant cst
+ | Eunop(op, e1) ->
+ let te1 = type_expr env lenv e1 in
+ let (targ, tres) = type_unary_operation op in
begin try
- unify_list targs tel
+ unify targ te1
with Error s ->
raise (Error (sprintf "In application of operator %s:\n%s"
- (name_of_operation op) s))
+ (name_of_unary_operation op) s))
end;
tres
- | Eload(chunk, addr, el) ->
- let tel = type_exprlist env lenv el in
+ | Ebinop(op, e1, e2) ->
+ let te1 = type_expr env lenv e1 in
+ let te2 = type_expr env lenv e2 in
+ let (targ1, targ2, tres) = type_binary_operation op in
begin try
- unify_list (type_addressing addr) tel
+ unify targ1 te1; unify targ2 te2
with Error s ->
- raise (Error (sprintf "In load %s %s:\n%s"
- (name_of_chunk chunk) (name_of_addressing addr) s))
+ raise (Error (sprintf "In application of operator %s:\n%s"
+ (name_of_binary_operation op) s))
+ end;
+ tres
+ | Eload(chunk, e) ->
+ let te = type_expr env lenv e in
+ begin try
+ unify tint te
+ with Error s ->
+ raise (Error (sprintf "In load %s:\n%s"
+ (name_of_chunk chunk) s))
end;
type_chunk chunk
- | Estore(chunk, addr, el, e1) ->
- let tel = type_exprlist env lenv el in
+ | Estore(chunk, e1, e2) ->
let te1 = type_expr env lenv e1 in
+ let te2 = type_expr env lenv e2 in
begin try
- unify_list (type_addressing addr) tel;
- unify (type_chunk chunk) te1
+ unify tint te1;
+ unify (type_chunk chunk) te2
with Error s ->
- raise (Error (sprintf "In store %s %s:\n%s"
- (name_of_chunk chunk) (name_of_addressing addr) s))
+ raise (Error (sprintf "In store %s:\n%s"
+ (name_of_chunk chunk) s))
end;
te1
| Ecall(sg, e1, el) ->
@@ -295,21 +263,13 @@ and type_exprlist env lenv el =
let tet = type_exprlist env lenv et in
(te1 :: tet)
-and type_condexpr env lenv ce =
- match ce with
- | CEtrue -> ()
- | CEfalse -> ()
- | CEcond(c, el) ->
- let tel = type_exprlist env lenv el in
- begin try
- unify_list (type_condition c) tel
- with Error s ->
- raise (Error (sprintf "In condition %s:\n%s" (name_of_condition c) s))
- end
- | CEcondition(ce1, ce2, ce3) ->
- type_condexpr env lenv ce1;
- type_condexpr env lenv ce2;
- type_condexpr env lenv ce3
+and type_condexpr env lenv e =
+ let te = type_expr env lenv e in
+ begin try
+ unify tint te
+ with Error s ->
+ raise (Error (sprintf "In condition:\n%s" s))
+ end
let rec type_stmt env blk ret s =
match s with
@@ -355,6 +315,15 @@ let rec type_stmt env blk ret s =
raise (Error (sprintf "In return:\n%s" s))
end
end
+ | Stailcall(sg, e1, el) ->
+ let te1 = type_expr env [] e1 in
+ let tel = type_exprlist env [] el in
+ begin try
+ unify tint te1;
+ unify_list (ty_of_sig_args sg.sig_args) tel
+ with Error s ->
+ raise (Error (sprintf "In tail call:\n%s" s))
+ end
let rec env_of_vars idl =
match idl with
diff --git a/caml/Camlcoq.ml b/caml/Camlcoq.ml
index c2115df..ec2447f 100644
--- a/caml/Camlcoq.ml
+++ b/caml/Camlcoq.ml
@@ -41,7 +41,7 @@ let z_of_camlint n =
let coqint_of_camlint : int32 -> Integers.int = z_of_camlint
-(* Strings *)
+(* Atoms (positive integers representing strings) *)
let atom_of_string = (Hashtbl.create 17 : (string, positive) Hashtbl.t)
let string_of_atom = (Hashtbl.create 17 : (positive, string) Hashtbl.t)
@@ -69,24 +69,6 @@ let rec coqlist_iter f = function
Coq_nil -> ()
| Coq_cons(a,l) -> f a; coqlist_iter f l
-(* Helpers *)
-
-let rec list_iter f = function
- [] -> ()
- | a::l -> f a; list_iter f l
-
-let rec list_memq x = function
- [] -> false
- | a::l -> a == x || list_memq x l
-
-let rec list_exists p = function
- [] -> false
- | a::l -> p a || list_exists p l
-
-let rec list_filter p = function
- [] -> []
- | x :: l -> if p x then x :: list_filter p l else list_filter p l
-
let rec length_coqlist = function
| Coq_nil -> 0
| Coq_cons (x, l) -> 1 + length_coqlist l
@@ -100,6 +82,31 @@ let array_of_coqlist = function
| Coq_cons(hd, tl) -> a.(i) <- hd; fill (i + 1) tl in
fill 1 tl
+(* Strings *)
+
+let char_of_ascii (Ascii.Ascii(a0, a1, a2, a3, a4, a5, a6, a7)) =
+ Char.chr( (if a0 then 1 else 0)
+ + (if a1 then 2 else 0)
+ + (if a2 then 4 else 0)
+ + (if a3 then 8 else 0)
+ + (if a4 then 16 else 0)
+ + (if a5 then 32 else 0)
+ + (if a6 then 64 else 0)
+ + (if a7 then 128 else 0))
+
+let coqstring_length s =
+ let rec len accu = function
+ | CString.EmptyString -> accu
+ | CString.CString(_, s) -> len (accu + 1) s
+ in len 0 s
+
+let camlstring_of_coqstring s =
+ let r = String.create (coqstring_length s) in
+ let rec fill pos = function
+ | CString.EmptyString -> r
+ | CString.CString(c, s) -> r.[pos] <- char_of_ascii c; fill (pos + 1) s
+ in fill 0 s
+
(* Timing facility *)
(*
diff --git a/caml/Coloringaux.ml b/caml/Coloringaux.ml
index a7c8db5..b3f4515 100644
--- a/caml/Coloringaux.ml
+++ b/caml/Coloringaux.ml
@@ -185,8 +185,8 @@ let init() =
let interfere n1 n2 =
if n1.degree < n2.degree
- then list_memq n2 n1.adjlist
- else list_memq n1 n2.adjlist
+ then List.memq n2 n1.adjlist
+ else List.memq n1 n2.adjlist
(* Add an edge to the graph. Assume edge is not in graph already *)
@@ -199,7 +199,7 @@ let addEdge n1 n2 =
(* Apply the given function to the relevant adjacent nodes of a node *)
let iterAdjacent f n =
- list_iter
+ List.iter
(fun n ->
match n.nstate with
| SelectStack | CoalescedNodes -> ()
@@ -214,12 +214,12 @@ let moveIsActiveOrWorklist m =
| _ -> false
let nodeMoves n =
- list_filter moveIsActiveOrWorklist n.movelist
+ List.filter moveIsActiveOrWorklist n.movelist
(* Determine whether a node is involved in a move *)
let moveRelated n =
- list_exists moveIsActiveOrWorklist n.movelist
+ List.exists moveIsActiveOrWorklist n.movelist
(*i
(* Check invariants *)
@@ -361,7 +361,7 @@ let build g typenv spillcosts =
(* Enable moves that have become low-degree related *)
let enableMoves n =
- list_iter
+ List.iter
(fun m ->
if m.mstate = ActiveMoves
then DLinkMove.move m activeMoves worklistMoves)
@@ -481,7 +481,7 @@ let freezeMoves u =
&& v.degree < num_available_registers.(v.regclass)
&& v.nstate <> Colored
then DLinkNode.move v freezeWorklist simplifyWorklist in
- list_iter freeze (nodeMoves u)
+ List.iter freeze (nodeMoves u)
(* Pick a move and freeze it *)
@@ -577,7 +577,7 @@ let find_slot conflicts typ =
let assign_color n =
let conflicts = ref Locset.empty in
- list_iter
+ List.iter
(fun n' ->
match (getAlias n').color with
| None -> ()
@@ -607,7 +607,7 @@ let graph_coloring (f: coq_function) (g: graph) (env: regenv) (regs: Regset.t)
init();
Array.fill start_points 0 num_register_classes 0;
let mapping = build g env (spill_costs f) in
- list_iter assign_color (nodeOrder []);
+ List.iter assign_color (nodeOrder []);
fun r ->
try location_of_node (getAlias (Hashtbl.find mapping r))
with Not_found -> R IT1 (* any location *)
diff --git a/caml/Main2.ml b/caml/Main2.ml
index ff9f350..e3399fb 100644
--- a/caml/Main2.ml
+++ b/caml/Main2.ml
@@ -94,8 +94,8 @@ let process_c_file sourcename =
(* Convert to PPC *)
let ppc =
match Main.transf_c_program csyntax with
- | Datatypes.Some x -> x
- | Datatypes.None ->
+ | Errors.OK x -> x
+ | Errors.Error msg ->
eprintf "Error in translation Csyntax -> PPC\n";
exit 2 in
(* Save PPC asm *)
@@ -111,10 +111,10 @@ let process_cminor_file sourcename =
match Main.transf_cminor_program
(CMtypecheck.type_program
(CMparser.prog CMlexer.token lb)) with
- | Datatypes.None ->
+ | Errors.Error msg ->
eprintf "Compiler failure\n";
exit 2
- | Datatypes.Some p ->
+ | Errors.OK p ->
let oc = open_out targetname in
PrintPPC.print_program oc p;
close_out oc
diff --git a/caml/PrintPPC.ml b/caml/PrintPPC.ml
index 3ee79d1..bf7b2cc 100644
--- a/caml/PrintPPC.ml
+++ b/caml/PrintPPC.ml
@@ -137,6 +137,8 @@ let print_instruction oc labels = function
fprintf oc " bf %a, %a\n" print_crbit bit print_label lbl
| Pbl s ->
fprintf oc " bl %a\n" print_symb s
+ | Pbs s ->
+ fprintf oc " b %a\n" print_symb s
| Pblr ->
fprintf oc " blr\n"
| Pbt(bit, lbl) ->
@@ -318,10 +320,6 @@ let print_instruction oc labels = function
fprintf oc " xoris %a, %a, %a\n" ireg r1 ireg r2 print_constant c
| Plabel lbl ->
if Labelset.mem lbl labels then fprintf oc "%a:\n" print_label lbl
- | Piundef r ->
- fprintf oc " # undef %a\n" ireg r
- | Pfundef r ->
- fprintf oc " # undef %a\n" freg r
let rec labels_of_code = function
| Coq_nil -> Labelset.empty
diff --git a/caml/RTLgenaux.ml b/caml/RTLgenaux.ml
index 336346a..61abecf 100644
--- a/caml/RTLgenaux.ml
+++ b/caml/RTLgenaux.ml
@@ -1,3 +1,47 @@
-open Cminor
+open Switch
+open CminorSel
let more_likely (c: condexpr) (ifso: stmt) (ifnot: stmt) = false
+
+module IntOrd =
+ struct
+ type t = Integers.int
+ let compare x y =
+ if Integers.Int.eq x y then 0 else
+ if Integers.Int.ltu x y then -1 else 1
+ end
+
+module IntSet = Set.Make(IntOrd)
+
+let normalize_table tbl =
+ let rec norm seen = function
+ | CList.Coq_nil -> []
+ | CList.Coq_cons(Datatypes.Coq_pair(key, act), rem) ->
+ if IntSet.mem key seen
+ then norm seen rem
+ else (key, act) :: norm (IntSet.add key seen) rem
+ in norm IntSet.empty tbl
+
+let compile_switch default table =
+ let sw = Array.of_list (normalize_table table) in
+ Array.stable_sort (fun (n1, _) (n2, _) -> IntOrd.compare n1 n2) sw;
+ let rec build lo hi =
+ match hi - lo with
+ | 0 ->
+ CTaction default
+ | 1 ->
+ CTifeq(fst sw.(lo), snd sw.(lo), CTaction default)
+ | 2 ->
+ CTifeq(fst sw.(lo), snd sw.(lo),
+ CTifeq(fst sw.(lo+1), snd sw.(lo+1),
+ CTaction default))
+ | 3 ->
+ CTifeq(fst sw.(lo), snd sw.(lo),
+ CTifeq(fst sw.(lo+1), snd sw.(lo+1),
+ CTifeq(fst sw.(lo+2), snd sw.(lo+2),
+ CTaction default)))
+ | _ ->
+ let mid = (lo + hi) / 2 in
+ CTiflt(fst sw.(mid), build lo mid, build mid hi)
+ in build 0 (Array.length sw)
+
diff --git a/caml/RTLtypingaux.ml b/caml/RTLtypingaux.ml
index 64f839a..5ed7e6e 100644
--- a/caml/RTLtypingaux.ml
+++ b/caml/RTLtypingaux.ml
@@ -32,10 +32,6 @@ let type_instr retty (Coq_pair(pc, i)) =
()
| Iop(Omove, _, _, _) ->
()
- | Iop(Oundef, Coq_nil, res, _) ->
- ()
- | Iop(Oundef, _, _, _) ->
- raise (Type_error "wrong Oundef")
| Iop(op, args, res, _) ->
let (Coq_pair(targs, tres)) = type_of_operation op in
set_types args targs; set_type res tres
@@ -61,6 +57,23 @@ let type_instr retty (Coq_pair(pc, i)) =
raise(Type_error (Printf.sprintf "type mismatch in Icall(%s): %s"
name msg))
end
+ | Itailcall(sg, ros, args) ->
+ begin try
+ begin match ros with
+ | Coq_inl r -> set_type r Tint
+ | Coq_inr _ -> ()
+ end;
+ set_types args sg.sig_args;
+ if sg.sig_res <> retty then
+ raise (Type_error "mismatch on return type")
+ with Type_error msg ->
+ let name =
+ match ros with
+ | Coq_inl _ -> "<reg>"
+ | Coq_inr id -> extern_atom id in
+ raise(Type_error (Printf.sprintf "type mismatch in Itailcall(%s): %s"
+ name msg))
+ end
| Ialloc(arg, res, _) ->
set_type arg Tint; set_type res Tint
| Icond(cond, args, _, _) ->
diff --git a/cfrontend/Cminorgen.v b/cfrontend/Cminorgen.v
index a3afae2..23faf78 100644
--- a/cfrontend/Cminorgen.v
+++ b/cfrontend/Cminorgen.v
@@ -3,6 +3,7 @@
Require Import FSets.
Require FSetAVL.
Require Import Coqlib.
+Require Import Errors.
Require Import Maps.
Require Import Ordered.
Require Import AST.
@@ -11,7 +12,9 @@ Require Mem.
Require Import Csharpminor.
Require Import Op.
Require Import Cminor.
-Require Cmconstr.
+
+Open Local Scope string_scope.
+Open Local Scope error_monad_scope.
(** The main task in translating Csharpminor to Cminor is to explicitly
stack-allocate local variables whose address is taken: these local
@@ -35,57 +38,12 @@ Require Cmconstr.
the ``normalize at assignment-time'' semantics of Csharpminor.
*)
-(** Translation of operators. *)
+(** Translation of constants. *)
-Definition make_op (op: Csharpminor.operation) (el: exprlist): option expr :=
- match el with
- | Enil =>
- match op with
- | Csharpminor.Ointconst n => Some(Eop (Ointconst n) Enil)
- | Csharpminor.Ofloatconst n => Some(Eop (Ofloatconst n) Enil)
- | _ => None
- end
- | Econs e1 Enil =>
- match op with
- | Csharpminor.Ocast8unsigned => Some(Cmconstr.cast8unsigned e1)
- | Csharpminor.Ocast8signed => Some(Cmconstr.cast8signed e1)
- | Csharpminor.Ocast16unsigned => Some(Cmconstr.cast16unsigned e1)
- | Csharpminor.Ocast16signed => Some(Cmconstr.cast16signed e1)
- | Csharpminor.Onotint => Some(Cmconstr.notint e1)
- | Csharpminor.Onotbool => Some(Cmconstr.notbool e1)
- | Csharpminor.Onegf => Some(Cmconstr.negfloat e1)
- | Csharpminor.Oabsf => Some(Cmconstr.absfloat e1)
- | Csharpminor.Osingleoffloat => Some(Cmconstr.singleoffloat e1)
- | Csharpminor.Ointoffloat => Some(Cmconstr.intoffloat e1)
- | Csharpminor.Ofloatofint => Some(Cmconstr.floatofint e1)
- | Csharpminor.Ofloatofintu => Some(Cmconstr.floatofintu e1)
- | _ => None
- end
- | Econs e1 (Econs e2 Enil) =>
- match op with
- | Csharpminor.Oadd => Some(Cmconstr.add e1 e2)
- | Csharpminor.Osub => Some(Cmconstr.sub e1 e2)
- | Csharpminor.Omul => Some(Cmconstr.mul e1 e2)
- | Csharpminor.Odiv => Some(Cmconstr.divs e1 e2)
- | Csharpminor.Odivu => Some(Cmconstr.divu e1 e2)
- | Csharpminor.Omod => Some(Cmconstr.mods e1 e2)
- | Csharpminor.Omodu => Some(Cmconstr.modu e1 e2)
- | Csharpminor.Oand => Some(Cmconstr.and e1 e2)
- | Csharpminor.Oor => Some(Cmconstr.or e1 e2)
- | Csharpminor.Oxor => Some(Cmconstr.xor e1 e2)
- | Csharpminor.Oshl => Some(Cmconstr.shl e1 e2)
- | Csharpminor.Oshr => Some(Cmconstr.shr e1 e2)
- | Csharpminor.Oshru => Some(Cmconstr.shru e1 e2)
- | Csharpminor.Oaddf => Some(Cmconstr.addf e1 e2)
- | Csharpminor.Osubf => Some(Cmconstr.subf e1 e2)
- | Csharpminor.Omulf => Some(Cmconstr.mulf e1 e2)
- | Csharpminor.Odivf => Some(Cmconstr.divf e1 e2)
- | Csharpminor.Ocmp c => Some(Cmconstr.cmp c e1 e2)
- | Csharpminor.Ocmpu c => Some(Cmconstr.cmpu c e1 e2)
- | Csharpminor.Ocmpf c => Some(Cmconstr.cmpf c e1 e2)
- | _ => None
- end
- | _ => None
+Definition transl_constant (cst: Csharpminor.constant): constant :=
+ match cst with
+ | Csharpminor.Ointconst n => Ointconst n
+ | Csharpminor.Ofloatconst n => Ofloatconst n
end.
(** [make_cast chunk e] returns a Cminor expression that normalizes
@@ -95,45 +53,38 @@ Definition make_op (op: Csharpminor.operation) (el: exprlist): option expr :=
Definition make_cast (chunk: memory_chunk) (e: expr): expr :=
match chunk with
- | Mint8signed => Cmconstr.cast8signed e
- | Mint8unsigned => Cmconstr.cast8unsigned e
- | Mint16signed => Cmconstr.cast16signed e
- | Mint16unsigned => Cmconstr.cast16unsigned e
+ | Mint8signed => Eunop Ocast8signed e
+ | Mint8unsigned => Eunop Ocast8unsigned e
+ | Mint16signed => Eunop Ocast16signed e
+ | Mint16unsigned => Eunop Ocast16unsigned e
| Mint32 => e
- | Mfloat32 => Cmconstr.singleoffloat e
+ | Mfloat32 => Eunop Osingleoffloat e
| Mfloat64 => e
end.
-Definition make_load (chunk: memory_chunk) (e: expr): expr :=
- Cmconstr.load chunk e.
-
Definition store_arg (chunk: memory_chunk) (e: expr) : expr :=
match e with
- | Eop op (Econs e1 Enil) =>
- match op with
- | Ocast8signed =>
- match chunk with Mint8signed => e1 | _ => e end
- | Ocast8unsigned =>
- match chunk with Mint8unsigned => e1 | _ => e end
- | Ocast16signed =>
- match chunk with Mint16signed => e1 | _ => e end
- | Ocast16unsigned =>
- match chunk with Mint16unsigned => e1 | _ => e end
- | Osingleoffloat =>
- match chunk with Mfloat32 => e1 | _ => e end
- | _ => e
- end
+ | Eunop Ocast8signed e1 =>
+ match chunk with Mint8signed => e1 | _ => e end
+ | Eunop Ocast8unsigned e1 =>
+ match chunk with Mint8unsigned => e1 | _ => e end
+ | Eunop Ocast16signed e1 =>
+ match chunk with Mint16signed => e1 | _ => e end
+ | Eunop Ocast16unsigned e1 =>
+ match chunk with Mint16unsigned => e1 | _ => e end
+ | Eunop Osingleoffloat e1 =>
+ match chunk with Mfloat32 => e1 | _ => e end
| _ => e
end.
Definition make_store (chunk: memory_chunk) (e1 e2: expr): stmt :=
- Sexpr(Cmconstr.store chunk e1 (store_arg chunk e2)).
+ Sexpr (Estore chunk e1 (store_arg chunk e2)).
Definition make_stackaddr (ofs: Z): expr :=
- Eop (Oaddrstack (Int.repr ofs)) Enil.
+ Econst (Oaddrstack (Int.repr ofs)).
Definition make_globaladdr (id: ident): expr :=
- Eop (Oaddrsymbol id Int.zero) Enil.
+ Econst (Oaddrsymbol id Int.zero).
(** Compile-time information attached to each Csharpminor
variable: global variables, local variables, function parameters.
@@ -156,134 +107,127 @@ Definition compilenv := PMap.t var_info.
(** Generation of Cminor code corresponding to accesses to Csharpminor
local variables: reads, assignments, and taking the address of. *)
-Definition var_get (cenv: compilenv) (id: ident): option expr :=
+Definition var_get (cenv: compilenv) (id: ident): res expr :=
match PMap.get id cenv with
| Var_local chunk =>
- Some(Evar id)
+ OK(Evar id)
| Var_stack_scalar chunk ofs =>
- Some(make_load chunk (make_stackaddr ofs))
+ OK(Eload chunk (make_stackaddr ofs))
| Var_global_scalar chunk =>
- Some(make_load chunk (make_globaladdr id))
+ OK(Eload chunk (make_globaladdr id))
| _ =>
- None
+ Error(msg "Cminorgen.var_get")
end.
-Definition var_set (cenv: compilenv) (id: ident) (rhs: expr): option stmt :=
+Definition var_set (cenv: compilenv) (id: ident) (rhs: expr): res stmt :=
match PMap.get id cenv with
| Var_local chunk =>
- Some(Sassign id (make_cast chunk rhs))
+ OK(Sassign id (make_cast chunk rhs))
| Var_stack_scalar chunk ofs =>
- Some(make_store chunk (make_stackaddr ofs) rhs)
+ OK(make_store chunk (make_stackaddr ofs) rhs)
| Var_global_scalar chunk =>
- Some(make_store chunk (make_globaladdr id) rhs)
+ OK(make_store chunk (make_globaladdr id) rhs)
| _ =>
- None
+ Error(msg "Cminorgen.var_set")
end.
-Definition var_addr (cenv: compilenv) (id: ident): option expr :=
+Definition var_addr (cenv: compilenv) (id: ident): res expr :=
match PMap.get id cenv with
- | Var_local chunk => None
- | Var_stack_scalar chunk ofs => Some (make_stackaddr ofs)
- | Var_stack_array ofs => Some (make_stackaddr ofs)
- | _ => Some (make_globaladdr id)
- end.
-
-(** The translation from Csharpminor to Cminor can fail, which we
- encode by returning option types ([None] denotes error).
- Propagation of errors is done in monadic style, using the following
- [bind] monadic composition operator, and a [do] notation inspired
- by Haskell's. *)
-
-Definition bind (A B: Set) (a: option A) (b: A -> option B): option B :=
- match a with
- | None => None
- | Some x => b x
+ | Var_local chunk => Error(msg "Cminorgen.var_addr")
+ | Var_stack_scalar chunk ofs => OK (make_stackaddr ofs)
+ | Var_stack_array ofs => OK (make_stackaddr ofs)
+ | _ => OK (make_globaladdr id)
end.
-Notation "'do' X <- A ; B" := (bind _ _ A (fun X => B))
- (at level 200, X ident, A at level 100, B at level 200).
-
(** Translation of expressions. All the hard work is done by the
[make_*] and [var_*] functions defined above. *)
Fixpoint transl_expr (cenv: compilenv) (e: Csharpminor.expr)
- {struct e}: option expr :=
+ {struct e}: res expr :=
match e with
| Csharpminor.Evar id => var_get cenv id
| Csharpminor.Eaddrof id => var_addr cenv id
- | Csharpminor.Eop op el =>
- do tel <- transl_exprlist cenv el; make_op op tel
+ | Csharpminor.Econst cst =>
+ OK (Econst (transl_constant cst))
+ | Csharpminor.Eunop op e1 =>
+ do te1 <- transl_expr cenv e1;
+ OK (Eunop op te1)
+ | Csharpminor.Ebinop op e1 e2 =>
+ do te1 <- transl_expr cenv e1;
+ do te2 <- transl_expr cenv e2;
+ OK (Ebinop op te1 te2)
| Csharpminor.Eload chunk e =>
- do te <- transl_expr cenv e; Some (make_load chunk te)
+ do te <- transl_expr cenv e;
+ OK (Eload chunk te)
| Csharpminor.Ecall sig e el =>
do te <- transl_expr cenv e;
do tel <- transl_exprlist cenv el;
- Some (Ecall sig te tel)
+ OK (Ecall sig te tel)
| Csharpminor.Econdition e1 e2 e3 =>
do te1 <- transl_expr cenv e1;
do te2 <- transl_expr cenv e2;
do te3 <- transl_expr cenv e3;
- Some (Cmconstr.conditionalexpr te1 te2 te3)
+ OK (Econdition te1 te2 te3)
| Csharpminor.Elet e1 e2 =>
do te1 <- transl_expr cenv e1;
do te2 <- transl_expr cenv e2;
- Some (Elet te1 te2)
+ OK (Elet te1 te2)
| Csharpminor.Eletvar n =>
- Some (Eletvar n)
+ OK (Eletvar n)
| Csharpminor.Ealloc e =>
do te <- transl_expr cenv e;
- Some (Ealloc te)
+ OK (Ealloc te)
end
with transl_exprlist (cenv: compilenv) (el: Csharpminor.exprlist)
- {struct el}: option exprlist :=
+ {struct el}: res exprlist :=
match el with
| Csharpminor.Enil =>
- Some Enil
+ OK Enil
| Csharpminor.Econs e1 e2 =>
do te1 <- transl_expr cenv e1;
do te2 <- transl_exprlist cenv e2;
- Some (Econs te1 te2)
+ OK (Econs te1 te2)
end.
(** Translation of statements. Entirely straightforward. *)
Fixpoint transl_stmt (cenv: compilenv) (s: Csharpminor.stmt)
- {struct s}: option stmt :=
+ {struct s}: res stmt :=
match s with
| Csharpminor.Sskip =>
- Some Sskip
+ OK Sskip
| Csharpminor.Sexpr e =>
- do te <- transl_expr cenv e; Some(Sexpr te)
+ do te <- transl_expr cenv e; OK(Sexpr te)
| Csharpminor.Sassign id e =>
do te <- transl_expr cenv e; var_set cenv id te
| Csharpminor.Sstore chunk e1 e2 =>
do te1 <- transl_expr cenv e1;
do te2 <- transl_expr cenv e2;
- Some (make_store chunk te1 te2)
+ OK (make_store chunk te1 te2)
| Csharpminor.Sseq s1 s2 =>
do ts1 <- transl_stmt cenv s1;
do ts2 <- transl_stmt cenv s2;
- Some (Sseq ts1 ts2)
+ OK (Sseq ts1 ts2)
| Csharpminor.Sifthenelse e s1 s2 =>
do te <- transl_expr cenv e;
do ts1 <- transl_stmt cenv s1;
do ts2 <- transl_stmt cenv s2;
- Some (Cmconstr.ifthenelse te ts1 ts2)
+ OK (Sifthenelse te ts1 ts2)
| Csharpminor.Sloop s =>
do ts <- transl_stmt cenv s;
- Some (Sloop ts)
+ OK (Sloop ts)
| Csharpminor.Sblock s =>
do ts <- transl_stmt cenv s;
- Some (Sblock ts)
+ OK (Sblock ts)
| Csharpminor.Sexit n =>
- Some (Sexit n)
+ OK (Sexit n)
| Csharpminor.Sswitch e cases default =>
- do te <- transl_expr cenv e; Some(Sswitch te cases default)
+ do te <- transl_expr cenv e; OK(Sswitch te cases default)
| Csharpminor.Sreturn None =>
- Some (Sreturn None)
+ OK (Sreturn None)
| Csharpminor.Sreturn (Some e) =>
- do te <- transl_expr cenv e; Some (Sreturn (Some te))
+ do te <- transl_expr cenv e; OK (Sreturn (Some te))
end.
(** Computation of the set of variables whose address is taken in
@@ -295,7 +239,10 @@ Fixpoint addr_taken_expr (e: Csharpminor.expr): Identset.t :=
match e with
| Csharpminor.Evar id => Identset.empty
| Csharpminor.Eaddrof id => Identset.add id Identset.empty
- | Csharpminor.Eop op el => addr_taken_exprlist el
+ | Csharpminor.Econst cst => Identset.empty
+ | Csharpminor.Eunop op e1 => addr_taken_expr e1
+ | Csharpminor.Ebinop op e1 e2 =>
+ Identset.union (addr_taken_expr e1) (addr_taken_expr e2)
| Csharpminor.Eload chunk e => addr_taken_expr e
| Csharpminor.Ecall sig e el =>
Identset.union (addr_taken_expr e) (addr_taken_exprlist el)
@@ -416,23 +363,23 @@ Fixpoint store_parameters
overflow machine arithmetic and lead to incorrect code. *)
Definition transl_function
- (gce: compilenv) (f: Csharpminor.function): option function :=
+ (gce: compilenv) (f: Csharpminor.function): res function :=
let (cenv, stacksize) := build_compilenv gce f in
if zle stacksize Int.max_signed then
do tbody <- transl_stmt cenv f.(Csharpminor.fn_body);
- Some (mkfunction
+ OK (mkfunction
(Csharpminor.fn_sig f)
(Csharpminor.fn_params_names f)
(Csharpminor.fn_vars_names f)
stacksize
(Sseq (store_parameters cenv f.(Csharpminor.fn_params)) tbody))
- else None.
+ else Error(msg "Cminorgen: too many local variables, stack size exceeded").
-Definition transl_fundef (gce: compilenv) (f: Csharpminor.fundef): option fundef :=
+Definition transl_fundef (gce: compilenv) (f: Csharpminor.fundef): res fundef :=
transf_partial_fundef (transl_function gce) f.
-Definition transl_globvar (vk: var_kind) := Some tt.
+Definition transl_globvar (vk: var_kind) := OK tt.
-Definition transl_program (p: Csharpminor.program) : option program :=
+Definition transl_program (p: Csharpminor.program) : res program :=
let gce := build_global_compilenv p in
transform_partial_program2 (transl_fundef gce) transl_globvar p.
diff --git a/cfrontend/Cminorgenproof.v b/cfrontend/Cminorgenproof.v
index ad31ff1..5bcb880 100644
--- a/cfrontend/Cminorgenproof.v
+++ b/cfrontend/Cminorgenproof.v
@@ -2,6 +2,7 @@
Require Import FSets.
Require Import Coqlib.
+Require Import Errors.
Require Import Maps.
Require Import AST.
Require Import Integers.
@@ -11,68 +12,49 @@ Require Import Mem.
Require Import Events.
Require Import Globalenvs.
Require Import Csharpminor.
-Require Import Op.
Require Import Cminor.
-Require Cmconstr.
Require Import Cminorgen.
-Require Import Cmconstrproof.
+
+Open Local Scope error_monad_scope.
Section TRANSLATION.
Variable prog: Csharpminor.program.
Variable tprog: program.
-Hypothesis TRANSL: transl_program prog = Some tprog.
+Hypothesis TRANSL: transl_program prog = OK tprog.
Let ge : Csharpminor.genv := Genv.globalenv prog.
Let tge: genv := Genv.globalenv tprog.
Let gce : compilenv := build_global_compilenv prog.
Lemma symbols_preserved:
forall (s: ident), Genv.find_symbol tge s = Genv.find_symbol ge s.
-Proof.
- intro. unfold ge, tge.
- apply Genv.find_symbol_transf_partial2 with (transl_fundef gce) transl_globvar.
- exact TRANSL.
-Qed.
+Proof (Genv.find_symbol_transf_partial2 (transl_fundef gce) transl_globvar _ TRANSL).
Lemma function_ptr_translated:
forall (b: block) (f: Csharpminor.fundef),
Genv.find_funct_ptr ge b = Some f ->
exists tf,
- Genv.find_funct_ptr tge b = Some tf /\ transl_fundef gce f = Some tf.
-Proof.
- intros.
- generalize
- (Genv.find_funct_ptr_transf_partial2 (transl_fundef gce) transl_globvar TRANSL H).
- case (transl_fundef gce f).
- intros tf [A B]. exists tf. tauto.
- intros [A B]. elim B. reflexivity.
-Qed.
+ Genv.find_funct_ptr tge b = Some tf /\ transl_fundef gce f = OK tf.
+Proof (Genv.find_funct_ptr_transf_partial2 (transl_fundef gce) transl_globvar TRANSL).
+
Lemma functions_translated:
forall (v: val) (f: Csharpminor.fundef),
Genv.find_funct ge v = Some f ->
exists tf,
- Genv.find_funct tge v = Some tf /\ transl_fundef gce f = Some tf.
-Proof.
- intros.
- generalize
- (Genv.find_funct_transf_partial2 (transl_fundef gce) transl_globvar TRANSL H).
- case (transl_fundef gce f).
- intros tf [A B]. exists tf. tauto.
- intros [A B]. elim B. reflexivity.
-Qed.
+ Genv.find_funct tge v = Some tf /\ transl_fundef gce f = OK tf.
+Proof (Genv.find_funct_transf_partial2 (transl_fundef gce) transl_globvar TRANSL).
Lemma sig_preserved:
forall f tf,
- transl_fundef gce f = Some tf ->
+ transl_fundef gce f = OK tf ->
Cminor.funsig tf = Csharpminor.funsig f.
Proof.
intros until tf; destruct f; simpl.
unfold transl_function. destruct (build_compilenv gce f).
- case (zle z Int.max_signed); try congruence.
- intro. case (transl_stmt c (Csharpminor.fn_body f)); simpl; try congruence.
- intros. inversion H. reflexivity.
- intro. inversion H; reflexivity.
+ case (zle z Int.max_signed); simpl; try congruence.
+ intros. monadInv H. monadInv EQ. reflexivity.
+ intro. inv H. reflexivity.
Qed.
Definition global_compilenv_match (ce: compilenv) (gv: gvarenv) : Prop :=
@@ -510,15 +492,12 @@ Lemma load_from_alloc_is_undef:
alloc m1 0 (size_chunk chunk) = (m2, b) ->
load chunk m2 b 0 = Some Vundef.
Proof.
- intros.
- assert (valid_block m2 b). eapply valid_new_block; eauto.
- assert (low_bound m2 b <= 0).
- generalize (low_bound_alloc _ _ b _ _ _ H). rewrite zeq_true. omega.
- assert (0 + size_chunk chunk <= high_bound m2 b).
- generalize (high_bound_alloc _ _ b _ _ _ H). rewrite zeq_true. omega.
- elim (load_in_bounds _ _ _ _ H0 H1 H2). intros v LOAD.
- assert (v = Vundef). eapply load_alloc_same; eauto.
- congruence.
+ intros.
+ assert (exists v, load chunk m2 b 0 = Some v).
+ apply valid_access_load.
+ eapply valid_access_alloc_same; eauto; omega.
+ destruct H0 as [v LOAD]. rewrite LOAD. decEq.
+ eapply load_alloc_same; eauto.
Qed.
Lemma match_env_alloc_same:
@@ -577,14 +556,20 @@ Proof.
contradiction.
(* other vars *)
generalize (me_vars0 id0); intros.
- inversion H6; econstructor; eauto.
- unfold e2; rewrite PTree.gso; auto.
- unfold f2, extend_inject, eq_block; rewrite zeq_false; auto.
- generalize (me_bounded0 _ _ _ H8). unfold block in *; omega.
- unfold e2; rewrite PTree.gso; eauto.
- unfold e2; rewrite PTree.gso; eauto.
- unfold e2; rewrite PTree.gso; eauto.
- unfold e2; rewrite PTree.gso; eauto.
+ inversion H6.
+ eapply match_var_local with (v := v); eauto.
+ unfold e2; rewrite PTree.gso; eauto.
+ eapply load_alloc_other; eauto.
+ unfold f2, extend_inject, eq_block; rewrite zeq_false; auto.
+ generalize (me_bounded0 _ _ _ H8). unfold block in *; omega.
+ econstructor; eauto.
+ unfold e2; rewrite PTree.gso; eauto.
+ econstructor; eauto.
+ unfold e2; rewrite PTree.gso; eauto.
+ econstructor; eauto.
+ unfold e2; rewrite PTree.gso; eauto.
+ econstructor; eauto.
+ unfold e2; rewrite PTree.gso; eauto.
(* lo <= hi *)
unfold block in *; omega.
(* me_bounded *)
@@ -629,9 +614,15 @@ Proof.
inversion H2. constructor; auto.
(* me_vars *)
intros. generalize (me_vars0 id); intro.
- inversion H5; econstructor; eauto.
- unfold f2, extend_inject, eq_block. rewrite zeq_false. auto.
- generalize (me_bounded0 _ _ _ H7). unfold block in *; omega.
+ inversion H5.
+ eapply match_var_local with (v := v); eauto.
+ eapply load_alloc_other; eauto.
+ unfold f2, extend_inject, eq_block. rewrite zeq_false. auto.
+ generalize (me_bounded0 _ _ _ H7). unfold block in *; omega.
+ econstructor; eauto.
+ econstructor; eauto.
+ econstructor; eauto.
+ econstructor; eauto.
(* me_bounded *)
intros until delta. unfold f2, extend_inject, eq_block.
case (zeq b0 b); intros. rewrite H5 in H0. omegaContradiction.
@@ -726,9 +717,10 @@ Proof.
(* me_vars *)
intros. generalize (me_vars0 id); intro. inversion H5.
(* var_local *)
- econstructor; eauto.
+ eapply match_var_local with (v := v); eauto.
+ eapply load_alloc_other; eauto.
generalize (me_bounded0 _ _ _ H7). intro.
- unfold f2, extend_inject. case (eq_block b0 b); intro.
+ unfold f2, extend_inject. case (zeq b0 b); intro.
subst b0. rewrite BEQ in H12. omegaContradiction.
auto.
(* var_stack_scalar *)
@@ -740,12 +732,12 @@ Proof.
(* var_global_array *)
econstructor; eauto.
(* me_bounded *)
- intros until delta. unfold f2, extend_inject. case (eq_block b0 b); intro.
+ intros until delta. unfold f2, extend_inject. case (zeq b0 b); intro.
intro. injection H5; clear H5; intros.
rewrite H6 in TBEQ. rewrite TBEQ in H3. omegaContradiction.
eauto.
(* me_inj *)
- intros until delta. unfold f2, extend_inject. case (eq_block b0 b); intros.
+ intros until delta. unfold f2, extend_inject. case (zeq b0 b); intros.
injection H5; clear H5; intros; subst b0 tb0 delta.
rewrite BEQ in H6. omegaContradiction.
eauto.
@@ -804,16 +796,7 @@ Qed.
(** * Correctness of Cminor construction functions *)
-Hint Resolve eval_negint eval_negfloat eval_absfloat eval_intoffloat
- eval_floatofint eval_floatofintu eval_notint eval_notbool
- eval_cast8signed eval_cast8unsigned eval_cast16signed
- eval_cast16unsigned eval_singleoffloat eval_add eval_add_ptr
- eval_add_ptr_2 eval_sub eval_sub_ptr_int eval_sub_ptr_ptr
- eval_mul eval_divs eval_mods eval_divu eval_modu
- eval_and eval_or eval_xor eval_shl eval_shr eval_shru
- eval_addf eval_subf eval_mulf eval_divf
- eval_cmp eval_cmp_null_r eval_cmp_null_l eval_cmp_ptr
- eval_cmpu eval_cmpf: evalexpr.
+Hint Resolve eval_Econst eval_Eunop eval_Ebinop eval_Eload: evalexpr.
Remark val_inject_val_of_bool:
forall f b, val_inject f (Val.of_bool b) (Val.of_bool b).
@@ -821,151 +804,146 @@ Proof.
intros; destruct b; unfold Val.of_bool, Vtrue, Vfalse; constructor.
Qed.
+Remark val_inject_bool_of_val:
+ forall f v b tv,
+ val_inject f v tv -> Val.bool_of_val v b -> Val.bool_of_val tv b.
+Proof.
+ intros. inv H; inv H0; constructor; auto.
+Qed.
+
+Remark val_inject_eval_compare_null:
+ forall f c i v,
+ eval_compare_null c i = Some v ->
+ val_inject f v v.
+Proof.
+ unfold eval_compare_null; intros.
+ destruct (Int.eq i Int.zero).
+ destruct c; inv H; unfold Vfalse, Vtrue; constructor.
+ discriminate.
+Qed.
+
Ltac TrivialOp :=
match goal with
- | [ |- exists x, _ /\ val_inject _ (Vint ?x) _ ] =>
+ | [ |- exists y, _ /\ val_inject _ (Vint ?x) _ ] =>
exists (Vint x); split;
[eauto with evalexpr | constructor]
- | [ |- exists x, _ /\ val_inject _ (Vfloat ?x) _ ] =>
+ | [ |- exists y, _ /\ val_inject _ (Vfloat ?x) _ ] =>
exists (Vfloat x); split;
[eauto with evalexpr | constructor]
- | [ |- exists x, _ /\ val_inject _ (Val.of_bool ?x) _ ] =>
+ | [ |- exists y, _ /\ val_inject _ (Val.of_bool ?x) _ ] =>
exists (Val.of_bool x); split;
[eauto with evalexpr | apply val_inject_val_of_bool]
+ | [ |- exists y, Some ?x = Some y /\ val_inject _ _ _ ] =>
+ exists x; split; [auto | econstructor; eauto]
| _ => idtac
end.
-Remark eval_compare_null_inv:
- forall c i v,
- Csharpminor.eval_compare_null c i = Some v ->
- i = Int.zero /\ (c = Ceq /\ v = Vfalse \/ c = Cne /\ v = Vtrue).
+(** Correctness of [transl_constant]. *)
+
+Lemma transl_constant_correct:
+ forall f sp cst v,
+ Csharpminor.eval_constant cst = Some v ->
+ exists tv,
+ eval_constant tge sp (transl_constant cst) = Some tv
+ /\ val_inject f v tv.
Proof.
- intros until v. unfold Csharpminor.eval_compare_null.
- predSpec Int.eq Int.eq_spec i Int.zero.
- case c; intro EQ; simplify_eq EQ; intro; subst v; tauto.
- congruence.
+ destruct cst; simpl; intros; inv H; TrivialOp.
Qed.
-(** Correctness of [make_op]. The generated Cminor code evaluates
- to a value that matches the result value of the Csharpminor operation,
- provided arguments match pairwise ([val_list_inject f] hypothesis). *)
+(** Compatibility of [eval_unop] with respect to [val_inject]. *)
-Lemma make_op_correct:
- forall al a op vl m2 v sp le te tm1 t tm2 tvl f,
- make_op op al = Some a ->
- Csharpminor.eval_operation op vl m2 = Some v ->
- eval_exprlist tge (Vptr sp Int.zero) le te tm1 al t tm2 tvl ->
- val_list_inject f vl tvl ->
- mem_inject f m2 tm2 ->
+Lemma eval_unop_compat:
+ forall f op v1 tv1 v,
+ eval_unop op v1 = Some v ->
+ val_inject f v1 tv1 ->
exists tv,
- eval_expr tge (Vptr sp Int.zero) le te tm1 a t tm2 tv
+ eval_unop op tv1 = Some tv
/\ val_inject f v tv.
Proof.
- intros.
- destruct al as [ | a1 al];
- [idtac | destruct al as [ | a2 al];
- [idtac | destruct al as [ | a3 al]]];
- simpl in H; try discriminate.
- (* Constant operators *)
- inversion H1. subst sp0 le0 e m tm1 tvl.
- inversion H2. subst vl.
- destruct op; simplify_eq H; intro; subst a;
- simpl in H0; injection H0; intro; subst v.
- (* intconst *)
- TrivialOp. econstructor. constructor. reflexivity.
- (* floatconst *)
- TrivialOp. econstructor. constructor. reflexivity.
- (* Unary operators *)
- inversion H1; clear H1; subst.
- inversion H11; clear H11; subst.
- rewrite E0_right.
- inversion H2; clear H2; subst. inversion H8; clear H8; subst.
- destruct op; simplify_eq H; intro; subst a;
- simpl in H0; destruct v1; simplify_eq H0; intro; subst v;
- inversion H7; subst v0;
- TrivialOp.
- change (Vint (Int.cast8unsigned i)) with (Val.cast8unsigned (Vint i)). eauto with evalexpr.
- change (Vint (Int.cast8signed i)) with (Val.cast8signed (Vint i)). eauto with evalexpr.
- change (Vint (Int.cast16unsigned i)) with (Val.cast16unsigned (Vint i)). eauto with evalexpr.
- change (Vint (Int.cast16signed i)) with (Val.cast16signed (Vint i)). eauto with evalexpr.
- replace (Int.eq i Int.zero) with (negb (negb (Int.eq i Int.zero))).
- eapply eval_notbool. eauto.
- generalize (Int.eq_spec i Int.zero). destruct (Int.eq i Int.zero); intro; simpl.
- rewrite H1; constructor. constructor; auto.
- apply negb_elim.
- unfold Vfalse; TrivialOp. change (Vint Int.zero) with (Val.of_bool (negb true)).
- eapply eval_notbool. eauto. constructor.
- change (Vfloat (Float.singleoffloat f0)) with (Val.singleoffloat (Vfloat f0)). eauto with evalexpr.
- (* Binary operations *)
- inversion H1; clear H1; subst. inversion H11; clear H11; subst.
- inversion H12; clear H12; subst. rewrite E0_right.
- inversion H2; clear H2; subst. inversion H9; clear H9; subst.
- inversion H10; clear H10; subst.
- destruct op; simplify_eq H; intro; subst a;
- simpl in H0; destruct v2; destruct v3; simplify_eq H0; intro; try subst v;
- inversion H7; inversion H8; subst v0; subst v1;
- TrivialOp.
- (* add int ptr *)
- exists (Vptr b2 (Int.add ofs2 i)); split.
- eauto with evalexpr. apply val_inject_ptr with x. auto.
- subst ofs2. repeat rewrite Int.add_assoc. decEq. apply Int.add_commut.
- (* add ptr int *)
- exists (Vptr b2 (Int.add ofs2 i0)); split.
- eauto with evalexpr. apply val_inject_ptr with x. auto.
- subst ofs2. repeat rewrite Int.add_assoc. decEq. apply Int.add_commut.
- (* sub ptr int *)
- exists (Vptr b2 (Int.sub ofs2 i0)); split.
- eauto with evalexpr. apply val_inject_ptr with x. auto.
- subst ofs2. apply Int.sub_add_l.
- (* sub ptr ptr *)
- destruct (eq_block b b0); simplify_eq H0; intro; subst v; subst b0.
- assert (b4 = b2). congruence. subst b4.
- exists (Vint (Int.sub ofs3 ofs2)); split.
- eauto with evalexpr.
- subst ofs2 ofs3. replace x0 with x. rewrite Int.sub_shifted. constructor.
- congruence.
- (* divs *)
- generalize (Int.eq_spec i0 Int.zero); destruct (Int.eq i0 Int.zero); intro;
- simplify_eq H0; intro; subst v. TrivialOp.
- (* divu *)
- generalize (Int.eq_spec i0 Int.zero); destruct (Int.eq i0 Int.zero); intro;
- simplify_eq H0; intro; subst v. TrivialOp.
- (* mods *)
- generalize (Int.eq_spec i0 Int.zero); destruct (Int.eq i0 Int.zero); intro;
- simplify_eq H0; intro; subst v. TrivialOp.
- (* modu *)
- generalize (Int.eq_spec i0 Int.zero); destruct (Int.eq i0 Int.zero); intro;
- simplify_eq H0; intro; subst v. TrivialOp.
- (* shl *)
- caseEq (Int.ltu i0 (Int.repr 32)); intro EQ; rewrite EQ in H0;
- simplify_eq H0; intro; subst v. TrivialOp.
- (* shr *)
- caseEq (Int.ltu i0 (Int.repr 32)); intro EQ; rewrite EQ in H0;
- simplify_eq H0; intro; subst v. TrivialOp.
- (* shru *)
- caseEq (Int.ltu i0 (Int.repr 32)); intro EQ; rewrite EQ in H0;
- simplify_eq H0; intro; subst v. TrivialOp.
- (* cmp int ptr *)
- elim (eval_compare_null_inv _ _ _ H0); intros; subst i1 i.
- exists v; split. eauto with evalexpr.
- elim H12; intros [A B]; subst v; unfold Vtrue, Vfalse; constructor.
- (* cmp ptr int *)
- elim (eval_compare_null_inv _ _ _ H0); intros; subst i1 i0.
- exists v; split. eauto with evalexpr.
- elim H12; intros [A B]; subst v; unfold Vtrue, Vfalse; constructor.
+ destruct op; simpl; intros.
+ inv H; inv H0; simpl; TrivialOp.
+ inv H; inv H0; simpl; TrivialOp.
+ inv H; inv H0; simpl; TrivialOp.
+ inv H; inv H0; simpl; TrivialOp.
+ inv H0; inv H. TrivialOp.
+ inv H0; inv H. TrivialOp. unfold Vfalse; TrivialOp.
+ inv H0; inv H; TrivialOp.
+ inv H0; inv H; TrivialOp.
+ inv H0; inv H; TrivialOp.
+ inv H; inv H0; simpl; TrivialOp.
+ inv H0; inv H; TrivialOp.
+ inv H0; inv H; TrivialOp.
+ inv H0; inv H; TrivialOp.
+Qed.
+
+(** Compatibility of [eval_binop] with respect to [val_inject]. *)
+
+Lemma eval_binop_compat:
+ forall f op v1 tv1 v2 tv2 v m tm,
+ eval_binop op v1 v2 m = Some v ->
+ val_inject f v1 tv1 ->
+ val_inject f v2 tv2 ->
+ mem_inject f m tm ->
+ exists tv,
+ eval_binop op tv1 tv2 tm = Some tv
+ /\ val_inject f v tv.
+Proof.
+ destruct op; simpl; intros.
+ inv H0; try discriminate; inv H1; inv H; TrivialOp.
+ repeat rewrite Int.add_assoc. decEq. apply Int.add_commut.
+ repeat rewrite Int.add_assoc. decEq. apply Int.add_commut.
+ inv H0; try discriminate; inv H1; inv H; TrivialOp.
+ apply Int.sub_add_l.
+ destruct (eq_block b1 b0); inv H4.
+ assert (b3 = b2) by congruence. subst b3.
+ unfold eq_block; rewrite zeq_true. TrivialOp.
+ replace x0 with x by congruence. decEq. decEq.
+ apply Int.sub_shifted.
+ inv H0; try discriminate; inv H1; inv H; TrivialOp.
+ inv H0; try discriminate; inv H1; inv H; TrivialOp.
+ destruct (Int.eq i0 Int.zero); inv H1. TrivialOp.
+ inv H0; try discriminate; inv H1; inv H; TrivialOp.
+ destruct (Int.eq i0 Int.zero); inv H1. TrivialOp.
+ inv H0; try discriminate; inv H1; inv H; TrivialOp.
+ destruct (Int.eq i0 Int.zero); inv H1. TrivialOp.
+ inv H0; try discriminate; inv H1; inv H; TrivialOp.
+ destruct (Int.eq i0 Int.zero); inv H1. TrivialOp.
+ inv H0; try discriminate; inv H1; inv H; TrivialOp.
+ inv H0; try discriminate; inv H1; inv H; TrivialOp.
+ inv H0; try discriminate; inv H1; inv H; TrivialOp.
+ inv H0; try discriminate; inv H1; inv H; TrivialOp.
+ destruct (Int.ltu i0 (Int.repr 32)); inv H1. TrivialOp.
+ inv H0; try discriminate; inv H1; inv H; TrivialOp.
+ destruct (Int.ltu i0 (Int.repr 32)); inv H1. TrivialOp.
+ inv H0; try discriminate; inv H1; inv H; TrivialOp.
+ destruct (Int.ltu i0 (Int.repr 32)); inv H1. TrivialOp.
+ inv H0; try discriminate; inv H1; inv H; TrivialOp.
+ inv H0; try discriminate; inv H1; inv H; TrivialOp.
+ inv H0; try discriminate; inv H1; inv H; TrivialOp.
+ inv H0; try discriminate; inv H1; inv H; TrivialOp.
+ inv H0; try discriminate; inv H1; inv H; TrivialOp.
+ exists v; split; auto. eapply val_inject_eval_compare_null; eauto.
+ exists v; split; auto. eapply val_inject_eval_compare_null; eauto.
(* cmp ptr ptr *)
- caseEq (valid_pointer m2 b (Int.signed i) && valid_pointer m2 b0 (Int.signed i0));
- intro EQ; rewrite EQ in H0; try discriminate.
- destruct (eq_block b b0); simplify_eq H0; intro; subst v b0.
- assert (b4 = b2); [congruence|subst b4].
- assert (x0 = x); [congruence|subst x0].
+ caseEq (valid_pointer m b1 (Int.signed ofs1) && valid_pointer m b0 (Int.signed ofs0));
+ intro EQ; rewrite EQ in H4; try discriminate.
+ destruct (eq_block b1 b0); inv H4.
+ assert (b3 = b2) by congruence. subst b3.
+ assert (x0 = x) by congruence. subst x0.
elim (andb_prop _ _ EQ); intros.
- exists (Val.of_bool (Int.cmp c ofs3 ofs2)); split.
- eauto with evalexpr.
- subst ofs2 ofs3. rewrite Int.translate_cmp.
- apply val_inject_val_of_bool.
+ exists (Val.of_bool (Int.cmp c ofs1 ofs0)); split.
+ exploit (Mem.valid_pointer_inject f m tm b0 ofs0); eauto.
+ intro VP; rewrite VP; clear VP.
+ exploit (Mem.valid_pointer_inject f m tm b0 ofs1); eauto.
+ intro VP; rewrite VP; clear VP.
+ unfold eq_block; rewrite zeq_true; simpl.
+ decEq. decEq. rewrite Int.translate_cmp. auto.
eapply valid_pointer_inject_no_overflow; eauto.
eapply valid_pointer_inject_no_overflow; eauto.
+ apply val_inject_val_of_bool.
+ (* *)
+ inv H0; try discriminate; inv H1; inv H; TrivialOp.
+ inv H0; try discriminate; inv H1; inv H; TrivialOp.
Qed.
(** Correctness of [make_cast]. Note that the resulting Cminor value is
@@ -980,35 +958,28 @@ Lemma make_cast_correct:
te tm1 (make_cast chunk a) t tm2 tv'
/\ val_inject f (Val.load_result chunk v) tv'.
Proof.
- intros. destruct chunk.
+ intros. destruct chunk; simpl make_cast.
exists (Val.cast8signed tv).
- split. apply eval_cast8signed; auto.
- inversion H0; simpl; constructor.
+ split. eauto with evalexpr. inversion H0; simpl; constructor.
exists (Val.cast8unsigned tv).
- split. apply eval_cast8unsigned; auto.
- inversion H0; simpl; constructor.
+ split. eauto with evalexpr. inversion H0; simpl; constructor.
exists (Val.cast16signed tv).
- split. apply eval_cast16signed; auto.
- inversion H0; simpl; constructor.
+ split. eauto with evalexpr. inversion H0; simpl; constructor.
exists (Val.cast16unsigned tv).
- split. apply eval_cast16unsigned; auto.
- inversion H0; simpl; constructor.
+ split. eauto with evalexpr. inversion H0; simpl; constructor.
- exists tv.
- split. simpl; auto.
- inversion H0; simpl; econstructor; eauto.
+ exists tv.
+ split. auto. inversion H0; simpl; econstructor; eauto.
exists (Val.singleoffloat tv).
- split. apply eval_singleoffloat; auto.
- inversion H0; simpl; constructor.
+ split. eauto with evalexpr. inversion H0; simpl; constructor.
- exists tv.
- split. simpl; auto.
- inversion H0; simpl; constructor.
+ exists tv.
+ split. auto. inversion H0; simpl; econstructor; eauto.
Qed.
Lemma make_stackaddr_correct:
@@ -1018,7 +989,7 @@ Lemma make_stackaddr_correct:
E0 tm (Vptr sp (Int.repr ofs)).
Proof.
intros; unfold make_stackaddr.
- eapply eval_Eop. econstructor. simpl. decEq. decEq.
+ econstructor. simpl. decEq. decEq.
rewrite Int.add_commut. apply Int.add_zero.
Qed.
@@ -1030,22 +1001,10 @@ Lemma make_globaladdr_correct:
E0 tm (Vptr b Int.zero).
Proof.
intros; unfold make_globaladdr.
- eapply eval_Eop. econstructor. simpl. rewrite H. auto.
+ econstructor. simpl. rewrite H. auto.
Qed.
-(** Correctness of [make_load] and [make_store]. *)
-
-Lemma make_load_correct:
- forall sp le te tm1 a t tm2 va chunk v,
- eval_expr tge (Vptr sp Int.zero) le te tm1 a t tm2 va ->
- Mem.loadv chunk tm2 va = Some v ->
- eval_expr tge (Vptr sp Int.zero) le
- te tm1 (make_load chunk a)
- t tm2 v.
-Proof.
- intros; unfold make_load.
- eapply eval_load; eauto.
-Qed.
+(** Correctness of [make_store]. *)
Lemma store_arg_content_inject:
forall f sp le te tm1 a t tm2 v va chunk,
@@ -1053,25 +1012,23 @@ Lemma store_arg_content_inject:
val_inject f v va ->
exists vb,
eval_expr tge (Vptr sp Int.zero) le te tm1 (store_arg chunk a) t tm2 vb
- /\ val_content_inject f (mem_chunk chunk) v vb.
+ /\ val_content_inject f chunk v vb.
Proof.
intros.
assert (exists vb,
eval_expr tge (Vptr sp Int.zero) le te tm1 a t tm2 vb
- /\ val_content_inject f (mem_chunk chunk) v vb).
+ /\ val_content_inject f chunk v vb).
exists va; split. assumption. constructor. assumption.
- inversion H; clear H; subst; simpl; trivial.
- inversion H2; clear H2; subst; trivial.
- inversion H4; clear H4; subst; trivial.
- rewrite E0_right. rewrite E0_right in H1.
- destruct op; trivial; destruct chunk; trivial;
- exists v0; (split; [auto|
- simpl in H3; inversion H3; clear H3; subst va;
- destruct v0; simpl in H0; inversion H0; subst; try (constructor; constructor)]).
- apply val_content_inject_8. apply Int.cast8_unsigned_signed.
- apply val_content_inject_8. apply Int.cast8_unsigned_idem.
- apply val_content_inject_16. apply Int.cast16_unsigned_signed.
- apply val_content_inject_16. apply Int.cast16_unsigned_idem.
+ destruct a; simpl store_arg; trivial;
+ destruct u; trivial;
+ destruct chunk; trivial;
+ inv H; simpl in H12; inv H12;
+ econstructor; (split; [eauto|idtac]);
+ destruct v1; simpl in H0; inv H0; try (constructor; constructor).
+ apply val_content_inject_8. auto. apply Int.cast8_unsigned_idem.
+ apply val_content_inject_8; auto. apply Int.cast8_unsigned_signed.
+ apply val_content_inject_16; auto. apply Int.cast16_unsigned_idem.
+ apply val_content_inject_16; auto. apply Int.cast16_unsigned_signed.
apply val_content_inject_32. apply Float.singleoffloat_idem.
Qed.
@@ -1098,13 +1055,11 @@ Proof.
intros [tv [EVAL VCINJ]].
exploit storev_mapped_inject_1; eauto.
intros [tm4 [STORE MEMINJ]].
- exploit eval_store. eexact H. eexact EVAL. eauto.
- intro EVALSTORE.
exists tm4.
- split. apply exec_Sexpr with tv. auto.
+ split. apply exec_Sexpr with tv. eapply eval_Estore; eauto.
split. auto.
unfold storev in STORE; destruct tvaddr; try discriminate.
- exploit store_inv; eauto. simpl. tauto.
+ eapply nextblock_store; eauto.
Qed.
(** Correctness of the variable accessors [var_get], [var_set]
@@ -1112,7 +1067,7 @@ Qed.
Lemma var_get_correct:
forall cenv id a f e te sp lo hi m cs tm b chunk v le,
- var_get cenv id = Some a ->
+ var_get cenv id = OK a ->
match_callstack f (mkframe cenv e te sp lo hi :: cs) m.(nextblock) tm.(nextblock) m ->
mem_inject f m tm ->
eval_var_ref prog e id b chunk ->
@@ -1138,7 +1093,7 @@ Proof.
unfold loadv. eexact H3.
intros [tv [LOAD INJ]].
exists tv; split.
- eapply make_load_correct; eauto. eapply make_stackaddr_correct; eauto.
+ econstructor; eauto. eapply make_stackaddr_correct; eauto.
auto.
(* var_global_scalar *)
inversion H2; [congruence|subst].
@@ -1151,14 +1106,14 @@ Proof.
generalize (loadv_inject _ _ _ _ _ _ _ H1 H12 H13).
intros [tv [LOAD INJ]].
exists tv; split.
- eapply make_load_correct; eauto. eapply make_globaladdr_correct; eauto.
+ econstructor; eauto. eapply make_globaladdr_correct; eauto.
auto.
Qed.
Lemma var_addr_correct:
forall cenv id a f e te sp lo hi m cs tm b le,
match_callstack f (mkframe cenv e te sp lo hi :: cs) m.(nextblock) tm.(nextblock) m ->
- var_addr cenv id = Some a ->
+ var_addr cenv id = OK a ->
eval_var_addr prog e id b ->
exists tv,
eval_expr tge (Vptr sp Int.zero) le te tm a E0 tm tv /\
@@ -1196,7 +1151,7 @@ Qed.
Lemma var_set_correct:
forall cenv id rhs a f e te sp lo hi m2 cs tm2 tm1 tv b chunk v m3 t,
- var_set cenv id rhs = Some a ->
+ var_set cenv id rhs = OK a ->
match_callstack f (mkframe cenv e te sp lo hi :: cs) m2.(nextblock) tm2.(nextblock) m2 ->
eval_expr tge (Vptr sp Int.zero) nil te tm1 rhs t tm2 tv ->
val_inject f v tv ->
@@ -1210,7 +1165,7 @@ Lemma var_set_correct:
Proof.
unfold var_set; intros.
assert (NEXTBLOCK: nextblock m3 = nextblock m2).
- exploit store_inv; eauto. simpl; tauto.
+ eapply nextblock_store; eauto.
inversion H0. subst.
assert (match_var f id e m2 te sp cenv!!id). inversion H19; auto.
inversion H6; subst; rewrite <- H7 in H; inversion H; subst; clear H.
@@ -1337,7 +1292,7 @@ Proof.
unfold f1; rewrite <- H2; eapply match_callstack_alloc_left; eauto.
rewrite <- H1. omega.
intros until delta; unfold f1, extend_inject, eq_block.
- rewrite (high_bound_alloc _ _ b _ _ _ H).
+ rewrite (high_bound_alloc _ _ _ _ _ H b).
case (zeq b b1); intros.
inversion H3. unfold sizeof; rewrite LV. omega.
generalize (BOUND _ _ H3). omega.
@@ -1350,7 +1305,7 @@ Proof.
exploit IHalloc_variables; eauto.
unfold f1; rewrite <- H2; eapply match_callstack_alloc_left; eauto.
intros until delta; unfold f1, extend_inject, eq_block.
- rewrite (high_bound_alloc _ _ b _ _ _ H).
+ rewrite (high_bound_alloc _ _ _ _ _ H b).
case (zeq b b1); intros. discriminate.
eapply BOUND; eauto.
intros [f' [INCR2 [MINJ2 MATCH2]]].
@@ -1373,7 +1328,7 @@ Proof.
unfold f1; rewrite <- H2; eapply match_callstack_alloc_left; eauto.
rewrite <- H1. omega.
intros until delta; unfold f1, extend_inject, eq_block.
- rewrite (high_bound_alloc _ _ b _ _ _ H).
+ rewrite (high_bound_alloc _ _ _ _ _ H b).
case (zeq b b1); intros.
inversion H6. unfold sizeof; rewrite LV. omega.
generalize (BOUND _ _ H6). omega.
@@ -1439,10 +1394,9 @@ Proof.
intros.
assert (SP: sp = nextblock tm). injection H2; auto.
unfold build_compilenv in H.
- eapply match_callstack_alloc_variables_rec with (sz' := sz); eauto.
- eapply valid_new_block; eauto.
- rewrite (low_bound_alloc _ _ sp _ _ _ H2). apply zeq_true.
- rewrite (high_bound_alloc _ _ sp _ _ _ H2). apply zeq_true.
+ eapply match_callstack_alloc_variables_rec with (sz' := sz); eauto with mem.
+ eapply low_bound_alloc_same; eauto.
+ eapply high_bound_alloc_same; eauto.
(* match_callstack *)
constructor. omega. change (valid_block tm' sp). eapply valid_new_block; eauto.
constructor.
@@ -1460,15 +1414,15 @@ Proof.
(* me_inj *)
intros until lv2. unfold Csharpminor.empty_env; rewrite PTree.gempty; congruence.
(* me_inv *)
- intros. exploit mi_mappedblocks; eauto. intros [A B].
+ intros. exploit mi_mappedblocks; eauto. intro A.
elim (fresh_block_alloc _ _ _ _ _ H2 A).
(* me_incr *)
- intros. exploit mi_mappedblocks; eauto. intros [A B].
+ intros. exploit mi_mappedblocks; eauto. intro A.
rewrite SP; auto.
rewrite SP; auto.
eapply alloc_right_inject; eauto.
omega.
- intros. exploit mi_mappedblocks; eauto. intros [A B].
+ intros. exploit mi_mappedblocks; eauto. unfold valid_block; intro.
unfold block in SP; omegaContradiction.
(* defined *)
intros. unfold te. apply set_locals_params_defined.
@@ -1569,7 +1523,7 @@ Proof.
inversion H18.
inversion NOREPET. subst hd tl.
assert (NEXT: nextblock m1 = nextblock m).
- exploit store_inv; eauto. simpl; tauto.
+ eapply nextblock_store; eauto.
generalize (me_vars0 id). intro. inversion H2; subst.
(* cenv!!id = Var_local chunk *)
assert (b0 = b). congruence. subst b0.
@@ -1724,43 +1678,6 @@ Qed.
(** * Semantic preservation for the translation *)
-(** These tactics simplify hypotheses of the form [f ... = Some x]. *)
-
-Ltac monadSimpl1 :=
- match goal with
- | [ |- (bind _ _ ?F ?G = Some ?X) -> _ ] =>
- unfold bind at 1;
- generalize (refl_equal F);
- pattern F at -1 in |- *;
- case F;
- [ (let EQ := fresh "EQ" in
- (intro; intro EQ;
- try monadSimpl1))
- | intros; discriminate ]
- | [ |- (None = Some _) -> _ ] =>
- intro; discriminate
- | [ |- (Some _ = Some _) -> _ ] =>
- let h := fresh "H" in
- (intro h; injection h; intro; clear h)
- end.
-
-Ltac monadSimpl :=
- match goal with
- | [ |- (bind _ _ ?F ?G = Some ?X) -> _ ] => monadSimpl1
- | [ |- (None = Some _) -> _ ] => monadSimpl1
- | [ |- (Some _ = Some _) -> _ ] => monadSimpl1
- | [ |- (?F _ _ _ _ _ _ _ = Some _) -> _ ] => simpl F; monadSimpl1
- | [ |- (?F _ _ _ _ _ _ = Some _) -> _ ] => simpl F; monadSimpl1
- | [ |- (?F _ _ _ _ _ = Some _) -> _ ] => simpl F; monadSimpl1
- | [ |- (?F _ _ _ _ = Some _) -> _ ] => simpl F; monadSimpl1
- | [ |- (?F _ _ _ = Some _) -> _ ] => simpl F; monadSimpl1
- | [ |- (?F _ _ = Some _) -> _ ] => simpl F; monadSimpl1
- | [ |- (?F _ = Some _) -> _ ] => simpl F; monadSimpl1
- end.
-
-Ltac monadInv H :=
- generalize H; monadSimpl.
-
(** The proof of semantic preservation uses simulation diagrams of the
following form:
<<
@@ -1790,7 +1707,7 @@ Ltac monadInv H :=
Definition eval_expr_prop
(le: Csharpminor.letenv) (e: Csharpminor.env) (m1: mem) (a: Csharpminor.expr) (t: trace) (m2: mem) (v: val) : Prop :=
forall cenv ta f1 tle te tm1 sp lo hi cs
- (TR: transl_expr cenv a = Some ta)
+ (TR: transl_expr cenv a = OK ta)
(LINJ: val_list_inject f1 le tle)
(MINJ: mem_inject f1 m1 tm1)
(MATCH: match_callstack f1
@@ -1808,7 +1725,7 @@ Definition eval_expr_prop
Definition eval_exprlist_prop
(le: Csharpminor.letenv) (e: Csharpminor.env) (m1: mem) (al: Csharpminor.exprlist) (t: trace) (m2: mem) (vl: list val) : Prop :=
forall cenv tal f1 tle te tm1 sp lo hi cs
- (TR: transl_exprlist cenv al = Some tal)
+ (TR: transl_exprlist cenv al = OK tal)
(LINJ: val_list_inject f1 le tle)
(MINJ: mem_inject f1 m1 tm1)
(MATCH: match_callstack f1
@@ -1826,7 +1743,7 @@ Definition eval_exprlist_prop
Definition eval_funcall_prop
(m1: mem) (fn: Csharpminor.fundef) (args: list val) (t: trace) (m2: mem) (res: val) : Prop :=
forall tfn f1 tm1 cs targs
- (TR: transl_fundef gce fn = Some tfn)
+ (TR: transl_fundef gce fn = OK tfn)
(MINJ: mem_inject f1 m1 tm1)
(MATCH: match_callstack f1 cs m1.(nextblock) tm1.(nextblock) m1)
(ARGSINJ: val_list_inject f1 args targs),
@@ -1852,7 +1769,7 @@ Inductive outcome_inject (f: meminj) : Csharpminor.outcome -> outcome -> Prop :=
Definition exec_stmt_prop
(e: Csharpminor.env) (m1: mem) (s: Csharpminor.stmt) (t: trace) (m2: mem) (out: Csharpminor.outcome): Prop :=
forall cenv ts f1 te1 tm1 sp lo hi cs
- (TR: transl_stmt cenv s = Some ts)
+ (TR: transl_stmt cenv s = OK ts)
(MINJ: mem_inject f1 m1 tm1)
(MATCH: match_callstack f1
(mkframe cenv e te1 sp lo hi :: cs)
@@ -1897,21 +1814,61 @@ Proof.
exists f1; exists tm1; exists tv. intuition eauto.
Qed.
-Lemma transl_expr_Eop_correct:
- forall (le : Csharpminor.letenv) (e : Csharpminor.env) (m : mem)
- (op : Csharpminor.operation) (al : Csharpminor.exprlist)
- (t: trace) (m1 : mem) (vl : list val) (v : val),
- Csharpminor.eval_exprlist prog le e m al t m1 vl ->
- eval_exprlist_prop le e m al t m1 vl ->
- Csharpminor.eval_operation op vl m1 = Some v ->
- eval_expr_prop le e m (Csharpminor.Eop op al) t m1 v.
-Proof.
- intros; red; intros. monadInv TR; intro EQ0.
+Lemma transl_expr_Econst_correct:
+ forall (le : Csharpminor.letenv) (e : Csharpminor.env) (m : mem)
+ (cst : Csharpminor.constant) (v : val),
+ Csharpminor.eval_constant cst = Some v ->
+ eval_expr_prop le e m (Csharpminor.Econst cst) E0 m v.
+Proof.
+ intros; red; intros; monadInv TR.
+ exploit transl_constant_correct; eauto.
+ intros [tv [EVAL VINJ]].
+ exists f1; exists tm1; exists tv. intuition eauto.
+ constructor; eauto.
+Qed.
+
+Lemma transl_expr_Eunop_correct:
+ forall (le : Csharpminor.letenv) (e : Csharpminor.env) (m : mem)
+ (op : unary_operation) (a : Csharpminor.expr) (t : trace)
+ (m1 : mem) (v1 v : val),
+ Csharpminor.eval_expr prog le e m a t m1 v1 ->
+ eval_expr_prop le e m a t m1 v1 ->
+ Csharpminor.eval_unop op v1 = Some v ->
+ eval_expr_prop le e m (Csharpminor.Eunop op a) t m1 v.
+Proof.
+ intros; red; intros. monadInv TR.
exploit H0; eauto.
intros [f2 [tm2 [tvl [EVAL1 [VINJ1 [MINJ1 [INCR1 MATCH1]]]]]]].
- exploit make_op_correct; eauto.
- intros [tv [EVAL2 VINJ2]].
- exists f2; exists tm2; exists tv. intuition.
+ exploit eval_unop_compat; eauto. intros [tv [EVAL VINJ]].
+ exists f2; exists tm2; exists tv; intuition.
+ econstructor; eauto.
+Qed.
+
+Lemma transl_expr_Ebinop_correct:
+ forall (le : Csharpminor.letenv) (e : Csharpminor.env) (m : mem)
+ (op : binary_operation) (a1 a2 : Csharpminor.expr) (t1 : trace)
+ (m1 : mem) (v1 : val) (t2 : trace) (m2 : mem) (v2 : val)
+ (t : trace) (v : val),
+ Csharpminor.eval_expr prog le e m a1 t1 m1 v1 ->
+ eval_expr_prop le e m a1 t1 m1 v1 ->
+ Csharpminor.eval_expr prog le e m1 a2 t2 m2 v2 ->
+ eval_expr_prop le e m1 a2 t2 m2 v2 ->
+ Csharpminor.eval_binop op v1 v2 m2 = Some v ->
+ t = t1 ** t2 ->
+ eval_expr_prop le e m (Csharpminor.Ebinop op a1 a2) t m2 v.
+Proof.
+ intros; red; intros. monadInv TR.
+ exploit H0; eauto.
+ intros [f2 [tm2 [tvl [EVAL1 [VINJ1 [MINJ1 [INCR1 MATCH1]]]]]]].
+ exploit H2.
+ eauto. eapply val_list_inject_incr; eauto. eauto. eauto.
+ intros [f3 [tm3 [tv2 [EVAL2 [VINJ2 [MINJ2 [INCR2 MATCH2]]]]]]].
+ exploit eval_binop_compat.
+ eauto. eapply val_inject_incr; eauto. eauto. eauto.
+ intros [tv [EVAL VINJ]].
+ exists f3; exists tm3; exists tv; intuition.
+ econstructor; eauto.
+ eapply inject_incr_trans; eauto.
Qed.
Lemma transl_expr_Eload_correct:
@@ -1931,7 +1888,7 @@ Proof.
intros [tv [TLOAD VINJ]].
exists f2; exists tm2; exists tv.
intuition.
- subst ta. eapply make_load_correct; eauto.
+ econstructor; eauto.
Qed.
Lemma transl_expr_Ecall_correct:
@@ -1951,7 +1908,7 @@ Lemma transl_expr_Ecall_correct:
t = t1 ** t2 ** t3 ->
eval_expr_prop le e m (Csharpminor.Ecall sig a bl) t m3 vres.
Proof.
- intros;red;intros. monadInv TR. subst ta.
+ intros;red;intros. monadInv TR.
exploit H0; eauto.
intros [f2 [tm2 [tv1 [EVAL1 [VINJ1 [MINJ1 [INCR1 MATCH1]]]]]]].
exploit H2.
@@ -1960,18 +1917,18 @@ Proof.
assert (tv1 = vf).
elim (Genv.find_funct_inv H3). intros bf VF. rewrite VF in H3.
rewrite Genv.find_funct_find_funct_ptr in H3.
- generalize (Genv.find_funct_ptr_inv H3). intro.
+ generalize (Genv.find_funct_ptr_negative H3). intro.
assert (match_globalenvs f2). eapply match_callstack_match_globalenvs; eauto.
- generalize (mg_functions _ H9 _ H8). intro.
+ generalize (mg_functions _ H7 _ H4). intro.
rewrite VF in VINJ1. inversion VINJ1. subst vf.
decEq. congruence.
- subst ofs2. replace x with 0. reflexivity. congruence.
+ subst ofs2. replace x1 with 0. reflexivity. congruence.
subst tv1. elim (functions_translated _ _ H3). intros tf [FIND TRF].
exploit H6; eauto.
intros [f4 [tm4 [tres [EVAL3 [VINJ3 [MINJ3 [INCR3 MATCH3]]]]]]].
exists f4; exists tm4; exists tres. intuition.
eapply eval_Ecall; eauto.
- rewrite <- H4. apply sig_preserved; auto.
+ apply sig_preserved; auto.
apply inject_incr_trans with f2; auto.
apply inject_incr_trans with f3; auto.
Qed.
@@ -1996,8 +1953,8 @@ Proof.
intros [f3 [tm3 [tv2 [EVAL2 [VINJ2 [MINJ2 [INCR2 MATCH2]]]]]]].
exists f3; exists tm3; exists tv2.
intuition.
- rewrite <- H6. subst t; eapply eval_conditionalexpr_true; eauto.
- inversion VINJ1; subst v1 tv1; simpl in H1; simpl; contradiction || auto.
+ eapply eval_Econdition with (b1 := true); eauto.
+ eapply val_inject_bool_of_val; eauto. apply Val.bool_of_true_val; eauto.
eapply inject_incr_trans; eauto.
Qed.
@@ -2021,8 +1978,8 @@ Proof.
intros [f3 [tm3 [tv2 [EVAL2 [VINJ2 [MINJ2 [INCR2 MATCH2]]]]]]].
exists f3; exists tm3; exists tv2.
intuition.
- rewrite <- H6. subst t; eapply eval_conditionalexpr_false; eauto.
- inversion VINJ1; subst v1 tv1; simpl in H1; simpl; contradiction || auto.
+ eapply eval_Econdition with (b1 := false); eauto.
+ eapply val_inject_bool_of_val; eauto. apply Val.bool_of_false_val; eauto.
eapply inject_incr_trans; eauto.
Qed.
@@ -2047,7 +2004,7 @@ Proof.
intros [f3 [tm3 [tv2 [EVAL2 [VINJ2 [MINJ2 [INCR2 MATCH2]]]]]]].
exists f3; exists tm3; exists tv2.
intuition.
- subst ta; eapply eval_Elet; eauto.
+ eapply eval_Elet; eauto.
eapply inject_incr_trans; eauto.
Qed.
@@ -2072,7 +2029,7 @@ Proof.
exploit val_list_inject_nth; eauto. intros [tv [A B]].
exists f1; exists tm1; exists tv.
intuition.
- subst ta. eapply eval_Eletvar; auto.
+ eapply eval_Eletvar; auto.
Qed.
Lemma transl_expr_Ealloc_correct:
@@ -2095,7 +2052,7 @@ Proof.
intros [MINJ3 INCR3].
exists (extend_inject b (Some (tb, 0)) f2);
exists tm3; exists (Vptr tb Int.zero).
- split. subst ta; econstructor; eauto.
+ split. econstructor; eauto.
split. econstructor. unfold extend_inject, eq_block. rewrite zeq_true. reflexivity.
reflexivity.
split. assumption.
@@ -2109,7 +2066,7 @@ Lemma transl_exprlist_Enil_correct:
Proof.
intros; red; intros. monadInv TR.
exists f1; exists tm1; exists (@nil val).
- intuition. subst tal; constructor.
+ intuition. constructor.
Qed.
Lemma transl_exprlist_Econs_correct:
@@ -2131,7 +2088,7 @@ Proof.
eauto. eapply val_list_inject_incr; eauto. eauto. eauto.
intros [f3 [tm3 [tv2 [EVAL2 [VINJ2 [MINJ3 [INCR3 MATCH3]]]]]]].
exists f3; exists tm3; exists (tv1 :: tv2).
- intuition. subst tal; econstructor; eauto.
+ intuition. econstructor; eauto.
constructor. eapply val_inject_incr; eauto. auto.
eapply inject_incr_trans; eauto.
Qed.
@@ -2149,15 +2106,11 @@ Lemma transl_funcall_internal_correct:
eval_funcall_prop m (Internal f) vargs t (free_list m3 lb) vres.
Proof.
intros; red. intros tfn f1 tm; intros.
- generalize TR; clear TR.
- unfold transl_fundef, transf_partial_fundef.
- caseEq (transl_function gce f); try congruence.
- intros tf TR EQ. inversion EQ; clear EQ; subst tfn.
- unfold transl_function in TR.
+ monadInv TR. generalize EQ.
+ unfold transl_function.
caseEq (build_compilenv gce f); intros cenv stacksize CENV.
- rewrite CENV in TR.
- destruct (zle stacksize Int.max_signed); try discriminate.
- monadInv TR. clear TR.
+ destruct (zle stacksize Int.max_signed); try congruence.
+ intro TR. monadInv TR.
caseEq (alloc tm 0 stacksize). intros tm1 sp ALLOC.
exploit function_entry_ok; eauto.
intros [f2 [te2 [tm2 [STOREPARAM [MINJ2 [INCR12 [MATCH2 BLOCKS]]]]]]].
@@ -2177,9 +2130,11 @@ Proof.
exists v2; split. auto. subst vres; auto.
contradiction.
destruct H5 as [tvres [TOUT VINJRES]].
+ assert (outcome_free_mem tout tm3 sp = Mem.free tm3 sp).
+ inversion OUTINJ; auto.
exists f3; exists (Mem.free tm3 sp); exists tvres.
(* execution *)
- split. rewrite <- H6; econstructor; simpl; eauto.
+ split. rewrite <- H5. econstructor; simpl; eauto.
apply exec_Sseq_continue with E0 te2 tm2 t.
exact STOREPARAM.
eexact EXECBODY.
@@ -2195,7 +2150,7 @@ Proof.
(* match_callstack *)
assert (forall bl mm, nextblock (free_list mm bl) = nextblock mm).
induction bl; intros. reflexivity. simpl. auto.
- unfold free; simpl nextblock. rewrite H5.
+ unfold free; simpl nextblock. rewrite H6.
eapply match_callstack_freelist; eauto.
intros. elim (BLOCKS b); intros B1 B2. generalize (B2 H7). omega.
Qed.
@@ -2206,8 +2161,7 @@ Lemma transl_funcall_external_correct:
event_match ef vargs t vres ->
eval_funcall_prop m (External ef) vargs t m vres.
Proof.
- intros; red; intros.
- simpl in TR. inversion TR; clear TR; subst tfn.
+ intros; red; intros. monadInv TR.
exploit event_match_inject; eauto. intros [A B].
exists f1; exists tm1; exists vres; intuition.
constructor; auto.
@@ -2219,7 +2173,7 @@ Lemma transl_stmt_Sskip_correct:
Proof.
intros; red; intros. monadInv TR.
exists f1; exists te1; exists tm1; exists Out_normal.
- intuition. subst ts; constructor. constructor.
+ intuition. constructor. constructor.
Qed.
Lemma transl_stmt_Sexpr_correct:
@@ -2233,7 +2187,7 @@ Proof.
exploit H0; eauto.
intros [f2 [tm2 [tv1 [EVAL1 [VINJ1 [MINJ2 [INCR2 MATCH2]]]]]]].
exists f2; exists te1; exists tm2; exists Out_normal.
- intuition. subst ts. econstructor; eauto.
+ intuition. econstructor; eauto.
constructor.
Qed.
@@ -2247,7 +2201,7 @@ Lemma transl_stmt_Sassign_correct:
store chunk m1 b 0 v = Some m2 ->
exec_stmt_prop e m (Csharpminor.Sassign id a) t m2 Csharpminor.Out_normal.
Proof.
- intros; red; intros. monadInv TR; intro EQ0.
+ intros; red; intros. monadInv TR.
exploit H0; eauto.
intros [f2 [tm2 [tv1 [EVAL1 [VINJ1 [MINJ1 [INCR12 MATCH1]]]]]]].
exploit var_set_correct; eauto.
@@ -2282,15 +2236,15 @@ Proof.
eapply val_inject_incr; eauto. eauto.
intros [tm4 [EVAL [MINJ4 NEXTBLOCK]]].
exists f3; exists te1; exists tm4; exists Out_normal.
- rewrite <- H6. subst t3. intuition.
+ intuition.
constructor.
eapply inject_incr_trans; eauto.
assert (val_inject f3 v1 tv1). eapply val_inject_incr; eauto.
unfold storev in H3; destruct v1; try discriminate.
inversion H4.
rewrite NEXTBLOCK. replace (nextblock m3) with (nextblock m2).
- eapply match_callstack_mapped; eauto. congruence.
- exploit store_inv; eauto. simpl; symmetry; tauto.
+ eapply match_callstack_mapped; eauto. congruence.
+ symmetry. eapply nextblock_store; eauto.
Qed.
Lemma transl_stmt_Sseq_continue_correct:
@@ -2309,7 +2263,7 @@ Proof.
exploit H2; eauto.
intros [f3 [te3 [tm3 [tout2 [EXEC2 [OINJ2 [MINJ3 [INCR3 MATCH3]]]]]]]].
exists f3; exists te3; exists tm3; exists tout2.
- intuition. subst ts; eapply exec_Sseq_continue; eauto.
+ intuition. eapply exec_Sseq_continue; eauto.
inversion OINJ1. subst tout1. auto.
eapply inject_incr_trans; eauto.
Qed.
@@ -2326,7 +2280,7 @@ Proof.
exploit H0; eauto.
intros [f2 [te2 [tm2 [tout1 [EXEC1 [OINJ1 [MINJ2 [INCR2 MATCH2]]]]]]]].
exists f2; exists te2; exists tm2; exists tout1.
- intuition. subst ts; eapply exec_Sseq_stop; eauto.
+ intuition. eapply exec_Sseq_stop; eauto.
inversion OINJ1; subst out tout1; congruence.
Qed.
@@ -2350,8 +2304,8 @@ Proof.
intros [f3 [te3 [tm3 [tout [EVAL2 [OINJ [MINJ3 [INCR3 MATCH3]]]]]]]].
exists f3; exists te3; exists tm3; exists tout.
intuition.
- subst ts t. eapply exec_ifthenelse_true; eauto.
- inversion VINJ1; subst v1 tv1; simpl in H1; simpl; contradiction || auto.
+ eapply exec_Sifthenelse with (b1 := true); eauto.
+ eapply val_inject_bool_of_val; eauto. apply Val.bool_of_true_val; auto.
eapply inject_incr_trans; eauto.
Qed.
@@ -2375,8 +2329,8 @@ Proof.
intros [f3 [te3 [tm3 [tout [EVAL2 [OINJ [MINJ3 [INCR3 MATCH3]]]]]]]].
exists f3; exists te3; exists tm3; exists tout.
intuition.
- subst ts t. eapply exec_ifthenelse_false; eauto.
- inversion VINJ1; subst v1 tv1; simpl in H1; simpl; contradiction || auto.
+ eapply exec_Sifthenelse with (b1 := false); eauto.
+ eapply val_inject_bool_of_val; eauto. apply Val.bool_of_false_val; auto.
eapply inject_incr_trans; eauto.
Qed.
@@ -2391,14 +2345,14 @@ Lemma transl_stmt_Sloop_loop_correct:
t = t1 ** t2 ->
exec_stmt_prop e m (Csharpminor.Sloop sl) t m2 out.
Proof.
- intros; red; intros. monadInv TR.
+ intros; red; intros. generalize TR; intro TR'; monadInv TR'.
exploit H0; eauto.
intros [f2 [te2 [tm2 [tout1 [EVAL1 [OINJ1 [MINJ2 [INCR2 MATCH2]]]]]]]].
exploit H2; eauto.
intros [f3 [te3 [tm3 [tout2 [EVAL2 [OINJ2 [MINJ3 [INCR3 MATCH3]]]]]]]].
exists f3; exists te3; exists tm3; exists tout2.
intuition.
- subst ts. eapply exec_Sloop_loop; eauto.
+ eapply exec_Sloop_loop; eauto.
inversion OINJ1; subst tout1; eauto.
eapply inject_incr_trans; eauto.
Qed.
@@ -2415,7 +2369,7 @@ Proof.
exploit H0; eauto.
intros [f2 [te2 [tm2 [tout1 [EVAL1 [OINJ1 [MINJ2 [INCR2 MATCH2]]]]]]]].
exists f2; exists te2; exists tm2; exists tout1.
- intuition. subst ts; eapply exec_Sloop_stop; eauto.
+ intuition. eapply exec_Sloop_stop; eauto.
inversion OINJ1; subst out tout1; congruence.
Qed.
@@ -2431,7 +2385,7 @@ Proof.
exploit H0; eauto.
intros [f2 [te2 [tm2 [tout1 [EVAL1 [OINJ1 [MINJ2 [INCR2 MATCH2]]]]]]]].
exists f2; exists te2; exists tm2; exists (outcome_block tout1).
- intuition. subst ts; eapply exec_Sblock; eauto.
+ intuition. eapply exec_Sblock; eauto.
inversion OINJ1; subst out tout1; simpl.
constructor.
destruct n; constructor.
@@ -2445,7 +2399,7 @@ Lemma transl_stmt_Sexit_correct:
Proof.
intros; red; intros. monadInv TR.
exists f1; exists te1; exists tm1; exists (Out_exit n).
- intuition. subst ts; constructor. constructor.
+ intuition. constructor. constructor.
Qed.
Lemma transl_stmt_Sswitch_correct:
@@ -2462,7 +2416,7 @@ Proof.
intros [f2 [tm2 [tv1 [EVAL [VINJ1 [MINJ2 [INCR MATCH2]]]]]]].
exists f2; exists te1; exists tm2;
exists (Out_exit (switch_target n default cases)). intuition.
- subst ts. constructor. inversion VINJ1. subst tv1. assumption.
+ constructor. inversion VINJ1. subst tv1. assumption.
constructor.
Qed.
@@ -2473,7 +2427,7 @@ Lemma transl_stmt_Sreturn_none_correct:
Proof.
intros; red; intros. monadInv TR.
exists f1; exists te1; exists tm1; exists (Out_return None).
- intuition. subst ts; constructor. constructor.
+ intuition. constructor. constructor.
Qed.
Lemma transl_stmt_Sreturn_some_correct:
@@ -2488,7 +2442,7 @@ Proof.
exploit H0; eauto.
intros [f2 [tm2 [tv1 [EVAL [VINJ1 [MINJ2 [INCR MATCH2]]]]]]].
exists f2; exists te1; exists tm2; exists (Out_return (Some tv1)).
- intuition. subst ts; econstructor; eauto. constructor; auto.
+ intuition. econstructor; eauto. constructor; auto.
Qed.
(** We conclude by an induction over the structure of the Csharpminor
@@ -2499,7 +2453,7 @@ Lemma transl_function_correct:
Csharpminor.eval_funcall prog m1 f vargs t m2 vres ->
eval_funcall_prop m1 f vargs t m2 vres.
Proof
- (eval_funcall_ind4 prog
+ (Csharpminor.eval_funcall_ind4 prog
eval_expr_prop
eval_exprlist_prop
eval_funcall_prop
@@ -2507,7 +2461,9 @@ Proof
transl_expr_Evar_correct
transl_expr_Eaddrof_correct
- transl_expr_Eop_correct
+ transl_expr_Econst_correct
+ transl_expr_Eunop_correct
+ transl_expr_Ebinop_correct
transl_expr_Eload_correct
transl_expr_Ecall_correct
transl_expr_Econdition_true_correct
@@ -2545,11 +2501,9 @@ Lemma match_globalenvs_init:
match_globalenvs f.
Proof.
intros. constructor.
- (* globalvars *)
- (* symbols *)
intros. split.
unfold f. rewrite zlt_true. auto. unfold m.
- eapply Genv.find_symbol_inv; eauto.
+ eapply Genv.find_symbol_not_fresh; eauto.
rewrite <- H. apply symbols_preserved.
intros. unfold f. rewrite zlt_true. auto.
generalize (nextblock_pos m). omega.
@@ -2566,20 +2520,10 @@ Proof.
intros t n [b [fn [m [FINDS [FINDF [SIG EVAL]]]]]].
elim (function_ptr_translated _ _ FINDF). intros tfn [TFIND TR].
set (m0 := Genv.init_mem prog) in *.
- set (f := fun b => if zlt b m0.(nextblock) then Some(b, 0) else None).
+ set (f := meminj_init m0).
assert (MINJ0: mem_inject f m0 m0).
- unfold f; constructor; intros.
- apply zlt_false; auto.
- destruct (zlt b0 (nextblock m0)); try discriminate.
- inversion H; subst b' delta.
- split. auto.
- constructor. compute. split; congruence. left; auto.
- intros; omega.
- generalize (Genv.initmem_block_init prog b0). fold m0. intros [idata EQ].
- rewrite EQ. simpl. apply Mem.contents_init_data_inject.
- destruct (zlt b1 (nextblock m0)); try discriminate.
- destruct (zlt b2 (nextblock m0)); try discriminate.
- left; congruence.
+ unfold f; apply init_inject.
+ unfold m0; apply Genv.initmem_inject_neutral.
assert (MATCH0: match_callstack f nil m0.(nextblock) m0.(nextblock) m0).
constructor. unfold f; apply match_globalenvs_init.
fold ge in EVAL.
diff --git a/cfrontend/Csem.v b/cfrontend/Csem.v
index 4cc8555..e24430c 100644
--- a/cfrontend/Csem.v
+++ b/cfrontend/Csem.v
@@ -1,6 +1,7 @@
(** * Dynamic semantics for the Clight language *)
Require Import Coqlib.
+Require Import Errors.
Require Import Maps.
Require Import Integers.
Require Import Floats.
@@ -559,7 +560,7 @@ with eval_lvalue: env -> mem -> expr -> trace -> mem -> block -> int -> Prop :=
| eval_Efield_struct: forall e m a t m1 l ofs id fList i ty delta,
eval_lvalue e m a t m1 l ofs ->
typeof a = Tstruct id fList ->
- field_offset i fList = Some delta ->
+ field_offset i fList = OK delta ->
eval_lvalue e m (Expr (Efield a i) ty)
t m1 l (Int.add ofs (Int.repr delta))
| eval_Efield_union: forall e m a t m1 l ofs id fList i ty,
diff --git a/cfrontend/Csharpminor.v b/cfrontend/Csharpminor.v
index f1d22d7..729814e 100644
--- a/cfrontend/Csharpminor.v
+++ b/cfrontend/Csharpminor.v
@@ -9,6 +9,7 @@ Require Import Values.
Require Import Mem.
Require Import Events.
Require Import Globalenvs.
+Require Cminor.
(** Abstract syntax *)
@@ -24,52 +25,21 @@ Require Import Globalenvs.
Unlike in Cminor (the next intermediate language of the back-end),
Csharpminor local variables reside in memory, and their address can
be taken using [Eaddrof] expressions.
+*)
+
+Inductive constant : Set :=
+ | Ointconst: int -> constant (**r integer constant *)
+ | Ofloatconst: float -> constant. (**r floating-point constant *)
- Another difference with Cminor is that Csharpminor is entirely
- processor-neutral. In particular, Csharpminor uses a standard set of
- operations: it does not reflect processor-specific operations nor
- addressing modes. *)
-
-Inductive operation : Set :=
- | Ointconst: int -> operation (**r integer constant *)
- | Ofloatconst: float -> operation (**r floating-point constant *)
- | Ocast8unsigned: operation (**r 8-bit zero extension *)
- | Ocast8signed: operation (**r 8-bit sign extension *)
- | Ocast16unsigned: operation (**r 16-bit zero extension *)
- | Ocast16signed: operation (**r 16-bit sign extension *)
- | Onotbool: operation (**r boolean negation *)
- | Onotint: operation (**r bitwise complement *)
- | Oadd: operation (**r integer addition *)
- | Osub: operation (**r integer subtraction *)
- | Omul: operation (**r integer multiplication *)
- | Odiv: operation (**r integer signed division *)
- | Odivu: operation (**r integer unsigned division *)
- | Omod: operation (**r integer signed modulus *)
- | Omodu: operation (**r integer unsigned modulus *)
- | Oand: operation (**r bitwise ``and'' *)
- | Oor: operation (**r bitwise ``or'' *)
- | Oxor: operation (**r bitwise ``xor'' *)
- | Oshl: operation (**r left shift *)
- | Oshr: operation (**r right signed shift *)
- | Oshru: operation (**r right unsigned shift *)
- | Onegf: operation (**r float opposite *)
- | Oabsf: operation (**r float absolute value *)
- | Oaddf: operation (**r float addition *)
- | Osubf: operation (**r float subtraction *)
- | Omulf: operation (**r float multiplication *)
- | Odivf: operation (**r float division *)
- | Osingleoffloat: operation (**r float truncation *)
- | Ointoffloat: operation (**r integer to float *)
- | Ofloatofint: operation (**r float to signed integer *)
- | Ofloatofintu: operation (**r float to unsigned integer *)
- | Ocmp: comparison -> operation (**r integer signed comparison *)
- | Ocmpu: comparison -> operation (**r integer unsigned comparison *)
- | Ocmpf: comparison -> operation. (**r float comparison *)
+Definition unary_operation : Set := Cminor.unary_operation.
+Definition binary_operation : Set := Cminor.binary_operation.
Inductive expr : Set :=
| Evar : ident -> expr (**r reading a scalar variable *)
| Eaddrof : ident -> expr (**r taking the address of a variable *)
- | Eop : operation -> exprlist -> expr (**r arithmetic operation *)
+ | Econst : constant -> expr
+ | Eunop : unary_operation -> expr -> expr
+ | Ebinop : binary_operation -> expr -> expr -> expr
| Eload : memory_chunk -> expr -> expr (**r memory read *)
| Ecall : signature -> expr -> exprlist -> expr (**r function call *)
| Econdition : expr -> expr -> expr -> expr (**r conditional expression *)
@@ -202,78 +172,15 @@ Definition global_var_env (p: program): gvarenv :=
(** Evaluation of operator applications. *)
-Definition eval_compare_null (c: comparison) (n: int) : option val :=
- if Int.eq n Int.zero
- then match c with Ceq => Some Vfalse | Cne => Some Vtrue | _ => None end
- else None.
-
-Definition eval_operation (op: operation) (vl: list val) (m: mem): option val :=
- match op, vl with
- | Ointconst n, nil => Some (Vint n)
- | Ofloatconst n, nil => Some (Vfloat n)
- | Ocast8unsigned, Vint n1 :: nil => Some (Vint (Int.cast8unsigned n1))
- | Ocast8signed, Vint n1 :: nil => Some (Vint (Int.cast8signed n1))
- | Ocast16unsigned, Vint n1 :: nil => Some (Vint (Int.cast16unsigned n1))
- | Ocast16signed, Vint n1 :: nil => Some (Vint (Int.cast16signed n1))
- | Onotbool, Vint n1 :: nil => Some (Val.of_bool (Int.eq n1 Int.zero))
- | Onotbool, Vptr b1 n1 :: nil => Some (Vfalse)
- | Onotint, Vint n1 :: nil => Some (Vint (Int.not n1))
- | Oadd, Vint n1 :: Vint n2 :: nil => Some (Vint (Int.add n1 n2))
- | Oadd, Vint n1 :: Vptr b2 n2 :: nil => Some (Vptr b2 (Int.add n2 n1))
- | Oadd, Vptr b1 n1 :: Vint n2 :: nil => Some (Vptr b1 (Int.add n1 n2))
- | Osub, Vint n1 :: Vint n2 :: nil => Some (Vint (Int.sub n1 n2))
- | Osub, Vptr b1 n1 :: Vint n2 :: nil => Some (Vptr b1 (Int.sub n1 n2))
- | Osub, Vptr b1 n1 :: Vptr b2 n2 :: nil =>
- if eq_block b1 b2 then Some (Vint (Int.sub n1 n2)) else None
- | Omul, Vint n1 :: Vint n2 :: nil => Some (Vint (Int.mul n1 n2))
- | Odiv, Vint n1 :: Vint n2 :: nil =>
- if Int.eq n2 Int.zero then None else Some (Vint (Int.divs n1 n2))
- | Odivu, Vint n1 :: Vint n2 :: nil =>
- if Int.eq n2 Int.zero then None else Some (Vint (Int.divu n1 n2))
- | Omod, Vint n1 :: Vint n2 :: nil =>
- if Int.eq n2 Int.zero then None else Some (Vint (Int.mods n1 n2))
- | Omodu, Vint n1 :: Vint n2 :: nil =>
- if Int.eq n2 Int.zero then None else Some (Vint (Int.modu n1 n2))
- | Oand, Vint n1 :: Vint n2 :: nil => Some (Vint (Int.and n1 n2))
- | Oor, Vint n1 :: Vint n2 :: nil => Some (Vint (Int.or n1 n2))
- | Oxor, Vint n1 :: Vint n2 :: nil => Some (Vint (Int.xor n1 n2))
- | Oshl, Vint n1 :: Vint n2 :: nil =>
- if Int.ltu n2 (Int.repr 32) then Some (Vint (Int.shl n1 n2)) else None
- | Oshr, Vint n1 :: Vint n2 :: nil =>
- if Int.ltu n2 (Int.repr 32) then Some (Vint (Int.shr n1 n2)) else None
- | Oshru, Vint n1 :: Vint n2 :: nil =>
- if Int.ltu n2 (Int.repr 32) then Some (Vint (Int.shru n1 n2)) else None
- | Onegf, Vfloat f1 :: nil => Some (Vfloat (Float.neg f1))
- | Oabsf, Vfloat f1 :: nil => Some (Vfloat (Float.abs f1))
- | Oaddf, Vfloat f1 :: Vfloat f2 :: nil => Some (Vfloat (Float.add f1 f2))
- | Osubf, Vfloat f1 :: Vfloat f2 :: nil => Some (Vfloat (Float.sub f1 f2))
- | Omulf, Vfloat f1 :: Vfloat f2 :: nil => Some (Vfloat (Float.mul f1 f2))
- | Odivf, Vfloat f1 :: Vfloat f2 :: nil => Some (Vfloat (Float.div f1 f2))
- | Osingleoffloat, Vfloat f1 :: nil =>
- Some (Vfloat (Float.singleoffloat f1))
- | Ointoffloat, Vfloat f1 :: nil =>
- Some (Vint (Float.intoffloat f1))
- | Ofloatofint, Vint n1 :: nil =>
- Some (Vfloat (Float.floatofint n1))
- | Ofloatofintu, Vint n1 :: nil =>
- Some (Vfloat (Float.floatofintu n1))
- | Ocmp c, Vint n1 :: Vint n2 :: nil =>
- Some (Val.of_bool(Int.cmp c n1 n2))
- | Ocmp c, Vptr b1 n1 :: Vptr b2 n2 :: nil =>
- if valid_pointer m b1 (Int.signed n1)
- && valid_pointer m b2 (Int.signed n2) then
- if eq_block b1 b2 then Some(Val.of_bool(Int.cmp c n1 n2)) else None
- else
- None
- | Ocmp c, Vptr b1 n1 :: Vint n2 :: nil => eval_compare_null c n2
- | Ocmp c, Vint n1 :: Vptr b2 n2 :: nil => eval_compare_null c n1
- | Ocmpu c, Vint n1 :: Vint n2 :: nil =>
- Some (Val.of_bool(Int.cmpu c n1 n2))
- | Ocmpf c, Vfloat f1 :: Vfloat f2 :: nil =>
- Some (Val.of_bool (Float.cmp c f1 f2))
- | _, _ => None
+Definition eval_constant (cst: constant) : option val :=
+ match cst with
+ | Ointconst n => Some (Vint n)
+ | Ofloatconst n => Some (Vfloat n)
end.
+Definition eval_unop := Cminor.eval_unop.
+Definition eval_binop := Cminor.eval_binop.
+
(** Allocation of local variables at function entry. Each variable is
bound to the reference to a fresh block of the appropriate size. *)
@@ -361,11 +268,22 @@ Inductive eval_expr:
forall le e m id b,
eval_var_addr e id b ->
eval_expr le e m (Eaddrof id) E0 m (Vptr b Int.zero)
- | eval_Eop:
- forall le e m op al t m1 vl v,
- eval_exprlist le e m al t m1 vl ->
- eval_operation op vl m1 = Some v ->
- eval_expr le e m (Eop op al) t m1 v
+ | eval_Econst:
+ forall le e m cst v,
+ eval_constant cst = Some v ->
+ eval_expr le e m (Econst cst) E0 m v
+ | eval_Eunop:
+ forall le e m op a t m1 v1 v,
+ eval_expr le e m a t m1 v1 ->
+ eval_unop op v1 = Some v ->
+ eval_expr le e m (Eunop op a) t m1 v
+ | eval_Ebinop:
+ forall le e m op a1 a2 t1 m1 v1 t2 m2 v2 t v,
+ eval_expr le e m a1 t1 m1 v1 ->
+ eval_expr le e m1 a2 t2 m2 v2 ->
+ eval_binop op v1 v2 m2 = Some v ->
+ t = t1 ** t2 ->
+ eval_expr le e m (Ebinop op a1 a2) t m2 v
| eval_Eload:
forall le e m chunk a t m1 v1 v,
eval_expr le e m a t m1 v1 ->
diff --git a/cfrontend/Cshmgen.v b/cfrontend/Cshmgen.v
index 664c6fc..5ab685d 100644
--- a/cfrontend/Cshmgen.v
+++ b/cfrontend/Cshmgen.v
@@ -1,19 +1,14 @@
Require Import Coqlib.
+Require Import Errors.
Require Import Integers.
Require Import Floats.
Require Import AST.
Require Import Csyntax.
+Require Import Cminor.
Require Import Csharpminor.
-(** The error monad *)
-
-Definition bind (A B: Set) (f: option A) (g: A -> option B) :=
- match f with None => None | Some x => g x end.
-
-Implicit Arguments bind [A B].
-
-Notation "'do' X <- A ; B" := (bind A (fun X => B))
- (at level 200, X ident, A at level 100, B at level 200).
+Open Local Scope string_scope.
+Open Local Scope error_monad_scope.
(** ** Operations on C types *)
@@ -22,28 +17,28 @@ Definition signature_of_function (f: Csyntax.function) : signature :=
(typlist_of_typelist (type_of_params (Csyntax.fn_params f)))
(opttyp_of_type (Csyntax.fn_return f)).
-Definition chunk_of_type (ty: type): option memory_chunk :=
+Definition chunk_of_type (ty: type): res memory_chunk :=
match access_mode ty with
- | By_value chunk => Some chunk
- | _ => None
+ | By_value chunk => OK chunk
+ | _ => Error (msg "Cshmgen.chunk_of_type")
end.
-Definition var_kind_of_type (ty: type): option var_kind :=
+Definition var_kind_of_type (ty: type): res var_kind :=
match ty with
- | Tint I8 Signed => Some(Vscalar Mint8signed)
- | Tint I8 Unsigned => Some(Vscalar Mint8unsigned)
- | Tint I16 Signed => Some(Vscalar Mint16signed)
- | Tint I16 Unsigned => Some(Vscalar Mint16unsigned)
- | Tint I32 _ => Some(Vscalar Mint32)
- | Tfloat F32 => Some(Vscalar Mfloat32)
- | Tfloat F64 => Some(Vscalar Mfloat64)
- | Tvoid => None
- | Tpointer _ => Some(Vscalar Mint32)
- | Tarray _ _ => Some(Varray (Csyntax.sizeof ty))
- | Tfunction _ _ => None
- | Tstruct _ fList => Some(Varray (Csyntax.sizeof ty))
- | Tunion _ fList => Some(Varray (Csyntax.sizeof ty))
- | Tcomp_ptr _ => Some(Vscalar Mint32)
+ | Tint I8 Signed => OK(Vscalar Mint8signed)
+ | Tint I8 Unsigned => OK(Vscalar Mint8unsigned)
+ | Tint I16 Signed => OK(Vscalar Mint16signed)
+ | Tint I16 Unsigned => OK(Vscalar Mint16unsigned)
+ | Tint I32 _ => OK(Vscalar Mint32)
+ | Tfloat F32 => OK(Vscalar Mfloat32)
+ | Tfloat F64 => OK(Vscalar Mfloat64)
+ | Tvoid => Error (msg "Cshmgen.var_kind_of_type(void)")
+ | Tpointer _ => OK(Vscalar Mint32)
+ | Tarray _ _ => OK(Varray (Csyntax.sizeof ty))
+ | Tfunction _ _ => Error (msg "Cshmgen.var_kind_of_type(function)")
+ | Tstruct _ fList => OK(Varray (Csyntax.sizeof ty))
+ | Tunion _ fList => OK(Varray (Csyntax.sizeof ty))
+ | Tcomp_ptr _ => OK(Vscalar Mint32)
end.
(** ** Csharpminor constructors *)
@@ -60,19 +55,14 @@ end.
denoting a case where the operation is not defined at the given types.
*)
-Definition make_intconst (n: int) := Eop (Ointconst n) Enil.
-
-Definition make_floatconst (f: float) := Eop (Ofloatconst f) Enil.
-
-Definition make_unop (op: operation) (e: expr) := Eop op (Econs e Enil).
+Definition make_intconst (n: int) := Econst (Ointconst n).
-Definition make_binop (op: operation) (e1 e2: expr) :=
- Eop op (Econs e1 (Econs e2 Enil)).
+Definition make_floatconst (f: float) := Econst (Ofloatconst f).
Definition make_floatofint (e: expr) (sg: signedness) :=
match sg with
- | Signed => make_unop Ofloatofint e
- | Unsigned => make_unop Ofloatofintu e
+ | Signed => Eunop Ofloatofint e
+ | Unsigned => Eunop Ofloatofintu e
end.
(* [make_boolean e ty] returns a Csharpminor expression that evaluates
@@ -84,98 +74,98 @@ Definition make_floatofint (e: expr) (sg: signedness) :=
*)
Definition make_boolean (e: expr) (ty: type) :=
match ty with
- | Tfloat _ => make_binop (Ocmpf Cne) e (make_floatconst Float.zero)
+ | Tfloat _ => Ebinop (Ocmpf Cne) e (make_floatconst Float.zero)
| _ => e
end.
Definition make_neg (e: expr) (ty: type) :=
match ty with
- | Tint _ _ => Some (make_binop Osub (make_intconst Int.zero) e)
- | Tfloat _ => Some (make_unop Onegf e)
- | _ => None
+ | Tint _ _ => OK (Eunop Onegint e)
+ | Tfloat _ => OK (Eunop Onegf e)
+ | _ => Error (msg "Cshmgen.make_neg")
end.
Definition make_notbool (e: expr) (ty: type) :=
match ty with
- | Tfloat _ => make_binop (Ocmpf Ceq) e (make_floatconst Float.zero)
- | _ => make_unop Onotbool e
+ | Tfloat _ => Ebinop (Ocmpf Ceq) e (make_floatconst Float.zero)
+ | _ => Eunop Onotbool e
end.
Definition make_notint (e: expr) (ty: type) :=
- make_unop Onotint e.
+ Eunop Onotint e.
Definition make_add (e1: expr) (ty1: type) (e2: expr) (ty2: type) :=
match classify_add ty1 ty2 with
- | add_case_ii => Some (make_binop Oadd e1 e2)
- | add_case_ff => Some (make_binop Oaddf e1 e2)
+ | add_case_ii => OK (Ebinop Oadd e1 e2)
+ | add_case_ff => OK (Ebinop Oaddf e1 e2)
| add_case_pi ty =>
let n := make_intconst (Int.repr (Csyntax.sizeof ty)) in
- Some (make_binop Oadd e1 (make_binop Omul n e2))
- | add_default => None
+ OK (Ebinop Oadd e1 (Ebinop Omul n e2))
+ | add_default => Error (msg "Cshmgen.make_add")
end.
Definition make_sub (e1: expr) (ty1: type) (e2: expr) (ty2: type) :=
match classify_sub ty1 ty2 with
- | sub_case_ii => Some (make_binop Osub e1 e2)
- | sub_case_ff => Some (make_binop Osubf e1 e2)
+ | sub_case_ii => OK (Ebinop Osub e1 e2)
+ | sub_case_ff => OK (Ebinop Osubf e1 e2)
| sub_case_pi ty =>
let n := make_intconst (Int.repr (Csyntax.sizeof ty)) in
- Some (make_binop Osub e1 (make_binop Omul n e2))
+ OK (Ebinop Osub e1 (Ebinop Omul n e2))
| sub_case_pp ty =>
let n := make_intconst (Int.repr (Csyntax.sizeof ty)) in
- Some (make_binop Odivu (make_binop Osub e1 e2) n)
- | sub_default => None
+ OK (Ebinop Odivu (Ebinop Osub e1 e2) n)
+ | sub_default => Error (msg "Cshmgen.make_sub")
end.
Definition make_mul (e1: expr) (ty1: type) (e2: expr) (ty2: type) :=
match classify_mul ty1 ty2 with
- | mul_case_ii => Some (make_binop Omul e1 e2)
- | mul_case_ff => Some (make_binop Omulf e1 e2)
- | mul_default => None
+ | mul_case_ii => OK (Ebinop Omul e1 e2)
+ | mul_case_ff => OK (Ebinop Omulf e1 e2)
+ | mul_default => Error (msg "Cshmgen.make_mul")
end.
Definition make_div (e1: expr) (ty1: type) (e2: expr) (ty2: type) :=
match classify_div ty1 ty2 with
- | div_case_I32unsi => Some (make_binop Odivu e1 e2)
- | div_case_ii => Some (make_binop Odiv e1 e2)
- | div_case_ff => Some (make_binop Odivf e1 e2)
- | div_default => None
+ | div_case_I32unsi => OK (Ebinop Odivu e1 e2)
+ | div_case_ii => OK (Ebinop Odiv e1 e2)
+ | div_case_ff => OK (Ebinop Odivf e1 e2)
+ | div_default => Error (msg "Cshmgen.make_div")
end.
Definition make_mod (e1: expr) (ty1: type) (e2: expr) (ty2: type) :=
match classify_mod ty1 ty2 with
- | mod_case_I32unsi => Some (make_binop Omodu e1 e2)
- | mod_case_ii=> Some (make_binop Omod e1 e2)
- | mod_default => None
+ | mod_case_I32unsi => OK (Ebinop Omodu e1 e2)
+ | mod_case_ii=> OK (Ebinop Omod e1 e2)
+ | mod_default => Error (msg "Cshmgen.make_mod")
end.
Definition make_and (e1: expr) (ty1: type) (e2: expr) (ty2: type) :=
- Some(make_binop Oand e1 e2).
+ OK(Ebinop Oand e1 e2).
Definition make_or (e1: expr) (ty1: type) (e2: expr) (ty2: type) :=
- Some(make_binop Oor e1 e2).
+ OK(Ebinop Oor e1 e2).
Definition make_xor (e1: expr) (ty1: type) (e2: expr) (ty2: type) :=
- Some(make_binop Oxor e1 e2).
+ OK(Ebinop Oxor e1 e2).
Definition make_shl (e1: expr) (ty1: type) (e2: expr) (ty2: type) :=
- Some(make_binop Oshl e1 e2).
+ OK(Ebinop Oshl e1 e2).
Definition make_shr (e1: expr) (ty1: type) (e2: expr) (ty2: type) :=
match classify_shr ty1 ty2 with
- | shr_case_I32unsi => Some (make_binop Oshru e1 e2)
- | shr_case_ii=> Some (make_binop Oshr e1 e2)
- | shr_default => None
+ | shr_case_I32unsi => OK (Ebinop Oshru e1 e2)
+ | shr_case_ii=> OK (Ebinop Oshr e1 e2)
+ | shr_default => Error (msg "Cshmgen.make_shr")
end.
Definition make_cmp (c: comparison) (e1: expr) (ty1: type) (e2: expr) (ty2: type) :=
match classify_cmp ty1 ty2 with
- | cmp_case_I32unsi => Some (make_binop (Ocmpu c) e1 e2)
- | cmp_case_ii => Some (make_binop (Ocmp c) e1 e2)
- | cmp_case_ff => Some (make_binop (Ocmpf c) e1 e2)
- | cmp_case_pi => Some (make_binop (Ocmp c) e1 e2)
- | cmp_case_pp => Some (make_binop (Ocmp c) e1 e2)
- | cmp_default => None
+ | cmp_case_I32unsi => OK (Ebinop (Ocmpu c) e1 e2)
+ | cmp_case_ii => OK (Ebinop (Ocmp c) e1 e2)
+ | cmp_case_ff => OK (Ebinop (Ocmpf c) e1 e2)
+ | cmp_case_pi => OK (Ebinop (Ocmp c) e1 e2)
+ | cmp_case_pp => OK (Ebinop (Ocmp c) e1 e2)
+ | cmp_default => Error (msg "Cshmgen.make_shr")
end.
Definition make_andbool (e1: expr) (ty1: type) (e2: expr) (ty2: type) :=
@@ -206,17 +196,17 @@ Definition make_orbool (e1: expr) (ty1: type) (e2: expr) (ty2: type) :=
Definition make_cast1 (from to: type) (e: expr) :=
match from, to with
| Tint _ uns, Tfloat _ => make_floatofint e uns
- | Tfloat _, Tint _ _ => make_unop Ointoffloat e
+ | Tfloat _, Tint _ _ => Eunop Ointoffloat e
| _, _ => e
end.
Definition make_cast2 (from to: type) (e: expr) :=
match to with
- | Tint I8 Signed => make_unop Ocast8signed e
- | Tint I8 Unsigned => make_unop Ocast8unsigned e
- | Tint I16 Signed => make_unop Ocast16signed e
- | Tint I16 Unsigned => make_unop Ocast16unsigned e
- | Tfloat F32 => make_unop Osingleoffloat e
+ | Tint I8 Signed => Eunop Ocast8signed e
+ | Tint I8 Unsigned => Eunop Ocast8unsigned e
+ | Tint I16 Signed => Eunop Ocast16signed e
+ | Tint I16 Unsigned => Eunop Ocast16unsigned e
+ | Tfloat F32 => Eunop Osingleoffloat e
| _ => e
end.
@@ -231,9 +221,9 @@ Definition make_cast (from to: type) (e: expr) :=
Definition make_load (addr: expr) (ty_res: type) :=
match (access_mode ty_res) with
- | By_value chunk => Some (Eload chunk addr)
- | By_reference => Some addr
- | By_nothing => None
+ | By_value chunk => OK (Eload chunk addr)
+ | By_reference => OK addr
+ | By_nothing => Error (msg "Cshmgen.make_load")
end.
(* [make_store addr ty_res rhs ty_rhs] stores the value of the
@@ -243,8 +233,8 @@ Definition make_load (addr: expr) (ty_res: type) :=
Definition make_store (addr: expr) (ty: type) (rhs: expr) :=
match access_mode ty with
- | By_value chunk => Some (Sstore chunk addr rhs)
- | _ => None
+ | By_value chunk => OK (Sstore chunk addr rhs)
+ | _ => Error (msg "Cshmgen.make_store")
end.
(** ** Reading and writing variables *)
@@ -258,9 +248,9 @@ Definition make_store (addr: expr) (ty: type) (rhs: expr) :=
Definition var_get (id: ident) (ty: type) :=
match access_mode ty with
- | By_value chunk => Some (Evar id)
- | By_reference => Some (Eaddrof id)
- | _ => None
+ | By_value chunk => OK (Evar id)
+ | By_reference => OK (Eaddrof id)
+ | _ => Error (MSG "Cshmgen.var_get " :: CTX id :: nil)
end.
(* [var_set id ty rhs] stores the value of the Csharpminor
@@ -269,21 +259,22 @@ Definition var_get (id: ident) (ty: type) :=
Definition var_set (id: ident) (ty: type) (rhs: expr) :=
match access_mode ty with
- | By_value chunk => Some (Sassign id rhs)
- | _ => None
+ | By_value chunk => OK (Sassign id rhs)
+ | _ => Error (MSG "Cshmgen.var_set " :: CTX id :: nil)
end.
(** ** Translation of operators *)
-Definition transl_unop (op: unary_operation) (a: expr) (ta: type) : option expr :=
+Definition transl_unop (op: Csyntax.unary_operation) (a: expr) (ta: type) : res expr :=
match op with
- | Csyntax.Onotbool => Some(make_notbool a ta)
- | Csyntax.Onotint => Some(make_notint a ta)
+ | Csyntax.Onotbool => OK(make_notbool a ta)
+ | Csyntax.Onotint => OK(make_notint a ta)
| Csyntax.Oneg => make_neg a ta
end.
-Definition transl_binop (op: binary_operation) (a: expr) (ta: type)
- (b: expr) (tb: type) : option expr :=
+Definition transl_binop (op: Csyntax.binary_operation)
+ (a: expr) (ta: type)
+ (b: expr) (tb: type) : res expr :=
match op with
| Csyntax.Oadd => make_add a ta b tb
| Csyntax.Osub => make_sub a ta b tb
@@ -315,12 +306,12 @@ Definition transl_binop (op: binary_operation) (a: expr) (ta: type)
a || b ---> a ? 1 : (b ? 1 : 0)
*)
-Fixpoint transl_expr (a: Csyntax.expr) {struct a} : option expr :=
+Fixpoint transl_expr (a: Csyntax.expr) {struct a} : res expr :=
match a with
| Expr (Csyntax.Econst_int n) _ =>
- Some(make_intconst n)
+ OK(make_intconst n)
| Expr (Csyntax.Econst_float n) _ =>
- Some(make_floatconst n)
+ OK(make_floatconst n)
| Expr (Csyntax.Evar id) ty =>
var_get id ty
| Expr (Csyntax.Ederef b) _ =>
@@ -337,7 +328,7 @@ Fixpoint transl_expr (a: Csyntax.expr) {struct a} : option expr :=
transl_binop op tb (typeof b) tc (typeof c)
| Expr (Csyntax.Ecast ty b) _ =>
do tb <- transl_expr b;
- Some (make_cast (typeof b) ty tb)
+ OK (make_cast (typeof b) ty tb)
| Expr (Csyntax.Eindex b c) ty =>
do tb <- transl_expr b;
do tc <- transl_expr c;
@@ -348,31 +339,33 @@ Fixpoint transl_expr (a: Csyntax.expr) {struct a} : option expr :=
| fun_case_f args res =>
do tb <- transl_expr b;
do tcl <- transl_exprlist cl;
- Some(Ecall (signature_of_type args res) tb tcl)
- | _ => None
+ OK(Ecall (signature_of_type args res) tb tcl)
+ | _ =>
+ Error(msg "Cshmgen.transl_expr(call)")
end
| Expr (Csyntax.Eandbool b c) _ =>
do tb <- transl_expr b;
do tc <- transl_expr c;
- Some(make_andbool tb (typeof b) tc (typeof c))
+ OK(make_andbool tb (typeof b) tc (typeof c))
| Expr (Csyntax.Eorbool b c) _ =>
do tb <- transl_expr b;
do tc <- transl_expr c;
- Some(make_orbool tb (typeof b) tc (typeof c))
+ OK(make_orbool tb (typeof b) tc (typeof c))
| Expr (Csyntax.Esizeof ty) _ =>
- Some(make_intconst (Int.repr (Csyntax.sizeof ty)))
+ OK(make_intconst (Int.repr (Csyntax.sizeof ty)))
| Expr (Csyntax.Efield b i) ty =>
match typeof b with
| Tstruct _ fld =>
do tb <- transl_lvalue b;
do ofs <- field_offset i fld;
make_load
- (make_binop Oadd tb (make_intconst (Int.repr ofs)))
+ (Ebinop Oadd tb (make_intconst (Int.repr ofs)))
ty
| Tunion _ fld =>
do tb <- transl_lvalue b;
make_load tb ty
- | _ => None
+ | _ =>
+ Error(msg "Cshmgen.transl_expr(field)")
end
end
@@ -381,10 +374,10 @@ Fixpoint transl_expr (a: Csyntax.expr) {struct a} : option expr :=
where the value of [a] is stored.
*)
-with transl_lvalue (a: Csyntax.expr) {struct a} : option expr :=
+with transl_lvalue (a: Csyntax.expr) {struct a} : res expr :=
match a with
| Expr (Csyntax.Evar id) _ =>
- Some (Eaddrof id)
+ OK (Eaddrof id)
| Expr (Csyntax.Ederef b) _ =>
transl_expr b
| Expr (Csyntax.Eindex b c) _ =>
@@ -396,25 +389,27 @@ with transl_lvalue (a: Csyntax.expr) {struct a} : option expr :=
| Tstruct _ fld =>
do tb <- transl_lvalue b;
do ofs <- field_offset i fld;
- Some (make_binop Oadd tb (make_intconst (Int.repr ofs)))
+ OK (Ebinop Oadd tb (make_intconst (Int.repr ofs)))
| Tunion _ fld =>
transl_lvalue b
- | _ => None
+ | _ =>
+ Error(msg "Cshmgen.transl_lvalue(field)")
end
- | _ => None
+ | _ =>
+ Error(msg "Cshmgen.transl_lvalue")
end
(* [transl_exprlist al] returns a list of Csharpminor expressions
that compute the values of the list [al] of Csyntax expressions.
Used for function applications. *)
-with transl_exprlist (al: Csyntax.exprlist): option exprlist :=
+with transl_exprlist (al: Csyntax.exprlist): res exprlist :=
match al with
- | Csyntax.Enil => Some Enil
+ | Csyntax.Enil => OK Enil
| Csyntax.Econs a1 a2 =>
do ta1 <- transl_expr a1;
do ta2 <- transl_exprlist a2;
- Some (Econs ta1 ta2)
+ OK (Econs ta1 ta2)
end.
(** ** Translation of statements *)
@@ -431,9 +426,9 @@ Definition is_variable (e: Csyntax.expr) : option ident :=
value of the CabsCoq expression [e] and performs an [exit 0] if [e]
evaluates to false.
*)
-Definition exit_if_false (e: Csyntax.expr) : option stmt :=
+Definition exit_if_false (e: Csyntax.expr) : res stmt :=
do te <- transl_expr e;
- Some(Sifthenelse
+ OK(Sifthenelse
(make_boolean te (typeof e))
Sskip
(Sexit 0%nat)).
@@ -497,13 +492,13 @@ Fixpoint switch_table (sl: labeled_statements) (k: nat) {struct sl} : list (int
| LScase ni _ rem => (ni, k) :: switch_table rem (k+1)
end.
-Fixpoint transl_statement (nbrk ncnt: nat) (s: Csyntax.statement) {struct s} : option stmt :=
+Fixpoint transl_statement (nbrk ncnt: nat) (s: Csyntax.statement) {struct s} : res stmt :=
match s with
| Csyntax.Sskip =>
- Some Sskip
+ OK Sskip
| Csyntax.Sexpr e =>
do te <- transl_expr e;
- Some (Sexpr te)
+ OK (Sexpr te)
| Csyntax.Sassign b c =>
match (is_variable b) with
| Some id =>
@@ -517,35 +512,35 @@ Fixpoint transl_statement (nbrk ncnt: nat) (s: Csyntax.statement) {struct s} : o
| Csyntax.Ssequence s1 s2 =>
do ts1 <- transl_statement nbrk ncnt s1;
do ts2 <- transl_statement nbrk ncnt s2;
- Some (Sseq ts1 ts2)
+ OK (Sseq ts1 ts2)
| Csyntax.Sifthenelse e s1 s2 =>
do te <- transl_expr e;
do ts1 <- transl_statement nbrk ncnt s1;
do ts2 <- transl_statement nbrk ncnt s2;
- Some (Sifthenelse (make_boolean te (typeof e)) ts1 ts2)
+ OK (Sifthenelse (make_boolean te (typeof e)) ts1 ts2)
| Csyntax.Swhile e s1 =>
do te <- exit_if_false e;
do ts1 <- transl_statement 1%nat 0%nat s1;
- Some (Sblock (Sloop (Sseq te (Sblock ts1))))
+ OK (Sblock (Sloop (Sseq te (Sblock ts1))))
| Csyntax.Sdowhile e s1 =>
do te <- exit_if_false e;
do ts1 <- transl_statement 1%nat 0%nat s1;
- Some (Sblock (Sloop (Sseq (Sblock ts1) te)))
+ OK (Sblock (Sloop (Sseq (Sblock ts1) te)))
| Csyntax.Sfor e1 e2 e3 s1 =>
do te1 <- transl_statement nbrk ncnt e1;
do te2 <- exit_if_false e2;
do te3 <- transl_statement nbrk ncnt e3;
do ts1 <- transl_statement 1%nat 0%nat s1;
- Some (Sseq te1 (Sblock (Sloop (Sseq te2 (Sseq (Sblock ts1) te3)))))
+ OK (Sseq te1 (Sblock (Sloop (Sseq te2 (Sseq (Sblock ts1) te3)))))
| Csyntax.Sbreak =>
- Some (Sexit nbrk)
+ OK (Sexit nbrk)
| Csyntax.Scontinue =>
- Some (Sexit ncnt)
+ OK (Sexit ncnt)
| Csyntax.Sreturn (Some e) =>
do te <- transl_expr e;
- Some (Sreturn (Some te))
+ OK (Sreturn (Some te))
| Csyntax.Sreturn None =>
- Some (Sreturn None)
+ OK (Sreturn None)
| Csyntax.Sswitch e sl =>
let cases := switch_table sl 0 in
let ncases := List.length cases in
@@ -554,11 +549,11 @@ Fixpoint transl_statement (nbrk ncnt: nat) (s: Csyntax.statement) {struct s} : o
end
with transl_lblstmts (nbrk ncnt: nat) (sl: labeled_statements) (body: stmt)
- {struct sl}: option stmt :=
+ {struct sl}: res stmt :=
match sl with
| LSdefault s =>
do ts <- transl_statement nbrk ncnt s;
- Some (Sblock (Sseq body ts))
+ OK (Sblock (Sseq body ts))
| LScase _ s rem =>
do ts <- transl_statement nbrk ncnt s;
transl_lblstmts (pred nbrk) (pred ncnt) rem (Sblock (Sseq body ts))
@@ -566,28 +561,31 @@ with transl_lblstmts (nbrk ncnt: nat) (sl: labeled_statements) (body: stmt)
(*** Translation of functions *)
+Definition prefix_var_name (id: ident) : errmsg :=
+ MSG "In local variable " :: CTX id :: MSG ":\n" :: nil.
+
Definition transl_params (l: list (ident * type)) :=
- AST.map_partial chunk_of_type l.
+ AST.map_partial prefix_var_name chunk_of_type l.
Definition transl_vars (l: list (ident * type)) :=
- AST.map_partial var_kind_of_type l.
+ AST.map_partial prefix_var_name var_kind_of_type l.
-Definition transl_function (f: Csyntax.function) : option function :=
+Definition transl_function (f: Csyntax.function) : res function :=
do tparams <- transl_params (Csyntax.fn_params f);
do tvars <- transl_vars (Csyntax.fn_vars f);
do tbody <- transl_statement 1%nat 0%nat (Csyntax.fn_body f);
- Some (mkfunction (signature_of_function f) tparams tvars tbody).
+ OK (mkfunction (signature_of_function f) tparams tvars tbody).
-Definition transl_fundef (f: Csyntax.fundef) : option fundef :=
+Definition transl_fundef (f: Csyntax.fundef) : res fundef :=
match f with
| Csyntax.Internal g =>
- do tg <- transl_function g; Some(AST.Internal tg)
+ do tg <- transl_function g; OK(AST.Internal tg)
| Csyntax.External id args res =>
- Some(AST.External (external_function id args res))
+ OK(AST.External (external_function id args res))
end.
(** ** Translation of programs *)
Definition transl_globvar (ty: type) := var_kind_of_type ty.
-Definition transl_program (p: Csyntax.program) : option program :=
+Definition transl_program (p: Csyntax.program) : res program :=
transform_partial_program2 transl_fundef transl_globvar p.
diff --git a/cfrontend/Cshmgenproof1.v b/cfrontend/Cshmgenproof1.v
index bee0782..7ffd156 100644
--- a/cfrontend/Cshmgenproof1.v
+++ b/cfrontend/Cshmgenproof1.v
@@ -1,6 +1,7 @@
(** * Correctness of the C front end, part 1: syntactic properties *)
Require Import Coqlib.
+Require Import Errors.
Require Import Maps.
Require Import Integers.
Require Import Floats.
@@ -12,64 +13,28 @@ Require Import Globalenvs.
Require Import Csyntax.
Require Import Csem.
Require Import Ctyping.
+Require Import Cminor.
Require Import Csharpminor.
Require Import Cshmgen.
-(** Monadic simplification *)
-
-Ltac monadSimpl1 :=
- match goal with
- | [ |- (bind ?F ?G = Some ?X) -> _ ] =>
- unfold bind at 1;
- generalize (refl_equal F);
- pattern F at -1 in |- *;
- case F;
- [ (let EQ := fresh "EQ" in
- (intro; intro EQ; try monadSimpl1))
- | intro; intro; discriminate ]
- | [ |- (None = Some _) -> _ ] =>
- intro; discriminate
- | [ |- (Some _ = Some _) -> _ ] =>
- let h := fresh "H" in
- (intro h; injection h; intro; clear h)
- | [ |- (_ = Some _) -> _ ] =>
- let EQ := fresh "EQ" in intro EQ
- end.
-
-Ltac monadSimpl :=
- match goal with
- | [ |- (bind ?F ?G = Some ?X) -> _ ] => monadSimpl1
- | [ |- (None = Some _) -> _ ] => monadSimpl1
- | [ |- (Some _ = Some _) -> _ ] => monadSimpl1
- | [ |- (?F _ _ _ _ _ _ = Some _) -> _ ] => unfold F; fold F; monadSimpl1
- | [ |- (?F _ _ _ _ _ = Some _) -> _ ] => unfold F; fold F; monadSimpl1
- | [ |- (?F _ _ _ _ = Some _) -> _ ] => unfold F; fold F; monadSimpl1
- | [ |- (?F _ _ _ = Some _) -> _ ] => unfold F; fold F; monadSimpl1
- | [ |- (?F _ _ = Some _) -> _ ] => unfold F; fold F; monadSimpl1
- | [ |- (?F _ = Some _) -> _ ] => unfold F; fold F; monadSimpl1
- end.
-
-Ltac monadInv H :=
- generalize H; monadSimpl.
-
(** Operations on types *)
Lemma transl_fundef_sig1:
forall f tf args res,
- transl_fundef f = Some tf ->
+ transl_fundef f = OK tf ->
classify_fun (type_of_fundef f) = fun_case_f args res ->
funsig tf = signature_of_type args res.
Proof.
intros. destruct f; monadInv H.
- monadInv EQ. rewrite <- H2. rewrite <- H3. simpl.
+ monadInv EQ. simpl.
simpl in H0. inversion H0. reflexivity.
- rewrite <- H2. simpl.
+ simpl.
simpl in H0. congruence.
Qed.
Lemma transl_fundef_sig2:
forall f tf args res,
- transl_fundef f = Some tf ->
+ transl_fundef f = OK tf ->
type_of_fundef f = Tfunction args res ->
funsig tf = signature_of_type args res.
Proof.
@@ -80,7 +45,7 @@ Qed.
Lemma var_kind_by_value:
forall ty chunk,
access_mode ty = By_value chunk ->
- var_kind_of_type ty = Some(Vscalar chunk).
+ var_kind_of_type ty = OK(Vscalar chunk).
Proof.
intros ty chunk; destruct ty; simpl; try congruence.
destruct i; try congruence; destruct s; congruence.
@@ -89,7 +54,7 @@ Qed.
Lemma sizeof_var_kind_of_type:
forall ty vk,
- var_kind_of_type ty = Some vk ->
+ var_kind_of_type ty = OK vk ->
Csharpminor.sizeof vk = Csyntax.sizeof ty.
Proof.
intros ty vk.
@@ -103,35 +68,35 @@ Qed.
(** ** Some properties of the translation functions *)
Lemma map_partial_names:
- forall (A B: Set) (f: A -> option B)
+ forall (A B: Set) (f: A -> res B)
(l: list (ident * A)) (tl: list (ident * B)),
- map_partial f l = Some tl ->
+ map_partial prefix_var_name f l = OK tl ->
List.map (@fst ident B) tl = List.map (@fst ident A) l.
Proof.
induction l; simpl.
intros. inversion H. reflexivity.
intro tl. destruct a as [id x]. destruct (f x); try congruence.
- caseEq (map_partial f l); intros; try congruence.
- inversion H0; subst tl. simpl. decEq. auto.
+ caseEq (map_partial prefix_var_name f l); simpl; intros; try congruence.
+ inv H0. simpl. decEq. auto.
Qed.
Lemma map_partial_append:
- forall (A B: Set) (f: A -> option B)
+ forall (A B: Set) (f: A -> res B)
(l1 l2: list (ident * A)) (tl1 tl2: list (ident * B)),
- map_partial f l1 = Some tl1 ->
- map_partial f l2 = Some tl2 ->
- map_partial f (l1 ++ l2) = Some (tl1 ++ tl2).
+ map_partial prefix_var_name f l1 = OK tl1 ->
+ map_partial prefix_var_name f l2 = OK tl2 ->
+ map_partial prefix_var_name f (l1 ++ l2) = OK (tl1 ++ tl2).
Proof.
induction l1; intros until tl2; simpl.
intros. inversion H. simpl; auto.
destruct a as [id x]. destruct (f x); try congruence.
- caseEq (map_partial f l1); intros; try congruence.
- inversion H0. rewrite (IHl1 _ _ _ H H1). auto.
+ caseEq (map_partial prefix_var_name f l1); simpl; intros; try congruence.
+ inv H0. rewrite (IHl1 _ _ _ H H1). auto.
Qed.
Lemma transl_params_names:
forall vars tvars,
- transl_params vars = Some tvars ->
+ transl_params vars = OK tvars ->
List.map (@fst ident memory_chunk) tvars = Ctyping.var_names vars.
Proof.
exact (map_partial_names _ _ chunk_of_type).
@@ -139,7 +104,7 @@ Qed.
Lemma transl_vars_names:
forall vars tvars,
- transl_vars vars = Some tvars ->
+ transl_vars vars = OK tvars ->
List.map (@fst ident var_kind) tvars = Ctyping.var_names vars.
Proof.
exact (map_partial_names _ _ var_kind_of_type).
@@ -148,8 +113,8 @@ Qed.
Lemma transl_names_norepet:
forall params vars sg tparams tvars body,
list_norepet (var_names params ++ var_names vars) ->
- transl_params params = Some tparams ->
- transl_vars vars = Some tvars ->
+ transl_params params = OK tparams ->
+ transl_vars vars = OK tvars ->
let f := Csharpminor.mkfunction sg tparams tvars body in
list_norepet (fn_params_names f ++ fn_vars_names f).
Proof.
@@ -161,35 +126,35 @@ Qed.
Lemma transl_vars_append:
forall l1 l2 tl1 tl2,
- transl_vars l1 = Some tl1 -> transl_vars l2 = Some tl2 ->
- transl_vars (l1 ++ l2) = Some (tl1 ++ tl2).
+ transl_vars l1 = OK tl1 -> transl_vars l2 = OK tl2 ->
+ transl_vars (l1 ++ l2) = OK (tl1 ++ tl2).
Proof.
exact (map_partial_append _ _ var_kind_of_type).
Qed.
Lemma transl_params_vars:
forall params tparams,
- transl_params params = Some tparams ->
+ transl_params params = OK tparams ->
transl_vars params =
- Some (List.map (fun id_chunk => (fst id_chunk, Vscalar (snd id_chunk))) tparams).
+ OK (List.map (fun id_chunk => (fst id_chunk, Vscalar (snd id_chunk))) tparams).
Proof.
induction params; intro tparams; simpl.
intros. inversion H. reflexivity.
destruct a as [id x].
unfold chunk_of_type. caseEq (access_mode x); try congruence.
intros chunk AM.
- caseEq (transl_params params); intros; try congruence.
- inversion H0.
+ caseEq (transl_params params); simpl; intros; try congruence.
+ inv H0.
rewrite (var_kind_by_value _ _ AM).
rewrite (IHparams _ H). reflexivity.
Qed.
Lemma transl_fn_variables:
forall params vars sg tparams tvars body,
- transl_params params = Some tparams ->
- transl_vars vars = Some tvars ->
+ transl_params params = OK tparams ->
+ transl_vars vars = OK tvars ->
let f := Csharpminor.mkfunction sg tparams tvars body in
- transl_vars (params ++ vars) = Some (fn_variables f).
+ transl_vars (params ++ vars) = OK (fn_variables f).
Proof.
intros.
generalize (transl_params_vars _ _ H); intro.
@@ -212,35 +177,36 @@ Qed.
Lemma transl_expr_lvalue:
forall ge e m1 a ty t m2 loc ofs ta,
Csem.eval_lvalue ge e m1 (Expr a ty) t m2 loc ofs ->
- transl_expr (Expr a ty) = Some ta ->
- (exists id, a = Csyntax.Evar id /\ var_get id ty = Some ta) \/
- (exists tb, transl_lvalue (Expr a ty) = Some tb /\
- make_load tb ty = Some ta).
+ transl_expr (Expr a ty) = OK ta ->
+ (exists id, a = Csyntax.Evar id /\ var_get id ty = OK ta) \/
+ (exists tb, transl_lvalue (Expr a ty) = OK tb /\
+ make_load tb ty = OK ta).
Proof.
intros. inversion H; subst; clear H; simpl in H0.
left; exists id; auto.
left; exists id; auto.
- monadInv H0. right. exists e0; split; auto.
- simpl. monadInv H0. right. exists e2; split; auto.
- simpl. rewrite H6 in H0. rewrite H6.
- monadInv H0. right.
- exists (make_binop Oadd e0 (make_intconst (Int.repr z))). split; auto.
- simpl. rewrite H10 in H0. rewrite H10.
- monadInv H0. right.
- exists e0; auto.
+ monadInv H0. right. exists x; split; auto.
+ simpl. monadInv H0. right. exists x1; split; auto.
+ simpl. rewrite EQ; rewrite EQ1. simpl. auto.
+ rewrite H6 in H0. monadInv H0. right.
+ exists (Ebinop Oadd x (make_intconst (Int.repr x0))). split; auto.
+ simpl. rewrite H6. rewrite EQ. rewrite EQ1. auto.
+ rewrite H10 in H0. monadInv H0. right.
+ exists x; split; auto.
+ simpl. rewrite H10. auto.
Qed.
Lemma transl_stmt_Sfor_start:
forall nbrk ncnt s1 e2 s3 s4 ts,
- transl_statement nbrk ncnt (Sfor s1 e2 s3 s4) = Some ts ->
+ transl_statement nbrk ncnt (Sfor s1 e2 s3 s4) = OK ts ->
exists ts1, exists ts2,
ts = Sseq ts1 ts2
- /\ transl_statement nbrk ncnt s1 = Some ts1
- /\ transl_statement nbrk ncnt (Sfor Csyntax.Sskip e2 s3 s4) = Some (Sseq Sskip ts2).
+ /\ transl_statement nbrk ncnt s1 = OK ts1
+ /\ transl_statement nbrk ncnt (Sfor Csyntax.Sskip e2 s3 s4) = OK (Sseq Sskip ts2).
Proof.
- intros. monadInv H. simpl.
- exists s; exists (Sblock (Sloop (Sseq s0 (Sseq (Sblock s5) s2)))).
- intuition.
+ intros. monadInv H. econstructor; econstructor.
+ split. reflexivity. split. auto. simpl.
+ rewrite EQ1; rewrite EQ0; rewrite EQ2; auto.
Qed.
(** Properties related to switch constructs *)
diff --git a/cfrontend/Cshmgenproof2.v b/cfrontend/Cshmgenproof2.v
index 0458bd5..8e2ce30 100644
--- a/cfrontend/Cshmgenproof2.v
+++ b/cfrontend/Cshmgenproof2.v
@@ -1,6 +1,7 @@
(** * Correctness of the C front end, part 2: Csharpminor construction functions *)
Require Import Coqlib.
+Require Import Errors.
Require Import Maps.
Require Import Integers.
Require Import Floats.
@@ -12,6 +13,7 @@ Require Import Globalenvs.
Require Import Csyntax.
Require Import Csem.
Require Import Ctyping.
+Require Import Cminor.
Require Import Csharpminor.
Require Import Cshmgen.
Require Import Cshmgenproof1.
@@ -25,14 +27,14 @@ Variable tprog: Csharpminor.program.
Lemma transl_lblstmts_exit:
forall e m1 t m2 sl body n tsl nbrk ncnt,
exec_stmt tprog e m1 body t m2 (Out_exit (lblstmts_length sl + n)) ->
- transl_lblstmts nbrk ncnt sl body = Some tsl ->
+ transl_lblstmts nbrk ncnt sl body = OK tsl ->
exec_stmt tprog e m1 tsl t m2 (outcome_block (Out_exit n)).
Proof.
induction sl; intros.
simpl in H; simpl in H0; monadInv H0.
- rewrite <- H2. constructor. apply exec_Sseq_stop. auto. congruence.
+ constructor. apply exec_Sseq_stop. auto. congruence.
simpl in H; simpl in H0; monadInv H0.
- eapply IHsl with (body := Sblock (Sseq body s0)); eauto.
+ eapply IHsl with (body := Sblock (Sseq body x)); eauto.
change (Out_exit (lblstmts_length sl + n))
with (outcome_block (Out_exit (S (lblstmts_length sl + n)))).
constructor. apply exec_Sseq_stop. auto. congruence.
@@ -41,15 +43,15 @@ Qed.
Lemma transl_lblstmts_return:
forall e m1 t m2 sl body optv tsl nbrk ncnt,
exec_stmt tprog e m1 body t m2 (Out_return optv) ->
- transl_lblstmts nbrk ncnt sl body = Some tsl ->
+ transl_lblstmts nbrk ncnt sl body = OK tsl ->
exec_stmt tprog e m1 tsl t m2 (Out_return optv).
Proof.
induction sl; intros.
simpl in H; simpl in H0; monadInv H0.
- rewrite <- H2. change (Out_return optv) with (outcome_block (Out_return optv)).
+ change (Out_return optv) with (outcome_block (Out_return optv)).
constructor. apply exec_Sseq_stop. auto. congruence.
simpl in H; simpl in H0; monadInv H0.
- eapply IHsl with (body := Sblock (Sseq body s0)); eauto.
+ eapply IHsl with (body := Sblock (Sseq body x)); eauto.
change (Out_return optv) with (outcome_block (Out_return optv)).
constructor. apply exec_Sseq_stop. auto. congruence.
Qed.
@@ -61,41 +63,18 @@ Lemma make_intconst_correct:
forall n le e m1,
Csharpminor.eval_expr tprog le e m1 (make_intconst n) E0 m1 (Vint n).
Proof.
- intros. unfold make_intconst. econstructor. constructor. reflexivity.
+ intros. unfold make_intconst. econstructor. constructor.
Qed.
Lemma make_floatconst_correct:
forall n le e m1,
Csharpminor.eval_expr tprog le e m1 (make_floatconst n) E0 m1 (Vfloat n).
Proof.
- intros. unfold make_floatconst. econstructor. constructor. reflexivity.
-Qed.
-
-Lemma make_unop_correct:
- forall op le e m1 a ta m2 va v,
- Csharpminor.eval_expr tprog le e m1 a ta m2 va ->
- eval_operation op (va :: nil) m2 = Some v ->
- Csharpminor.eval_expr tprog le e m1 (make_unop op a) ta m2 v.
-Proof.
- intros. unfold make_unop. econstructor. econstructor. eauto. constructor.
- traceEq. auto.
-Qed.
-
-Lemma make_binop_correct:
- forall op le e m1 a ta m2 va b tb m3 vb t v,
- Csharpminor.eval_expr tprog le e m1 a ta m2 va ->
- Csharpminor.eval_expr tprog le e m2 b tb m3 vb ->
- eval_operation op (va :: vb :: nil) m3 = Some v ->
- t = ta ** tb ->
- Csharpminor.eval_expr tprog le e m1 (make_binop op a b) t m3 v.
-Proof.
- intros. unfold make_binop.
- econstructor. econstructor. eauto. econstructor. eauto. constructor.
- reflexivity. traceEq. auto.
+ intros. unfold make_floatconst. econstructor. constructor.
Qed.
Hint Resolve make_intconst_correct make_floatconst_correct
- make_unop_correct make_binop_correct: cshm.
+ eval_Eunop eval_Ebinop: cshm.
Hint Extern 2 (@eq trace _ _) => traceEq: cshm.
Remark Vtrue_is_true: Val.is_true Vtrue.
@@ -120,7 +99,7 @@ Proof.
destruct ty; simpl;
try (exists v; intuition; inversion VTRUE; simpl; auto; fail).
exists Vtrue; split.
- eapply make_binop_correct; eauto with cshm.
+ econstructor; eauto with cshm.
inversion VTRUE; simpl.
replace (Float.cmp Cne f0 Float.zero) with (negb (Float.cmp Ceq f0 Float.zero)).
rewrite Float.eq_zero_false. reflexivity. auto.
@@ -140,7 +119,7 @@ Proof.
destruct ty; simpl;
try (exists v; intuition; inversion VFALSE; simpl; auto; fail).
exists Vfalse; split.
- eapply make_binop_correct; eauto with cshm.
+ econstructor; eauto with cshm.
inversion VFALSE; simpl.
replace (Float.cmp Cne Float.zero Float.zero) with (negb (Float.cmp Ceq Float.zero Float.zero)).
rewrite Float.eq_zero_true. reflexivity.
@@ -151,13 +130,13 @@ Qed.
Lemma make_neg_correct:
forall a tya c ta va v le e m1 m2,
sem_neg va tya = Some v ->
- make_neg a tya = Some c ->
+ make_neg a tya = OK c ->
eval_expr tprog le e m1 a ta m2 va ->
eval_expr tprog le e m1 c ta m2 v.
Proof.
intros until m2; intro SEM. unfold make_neg.
functional inversion SEM; intros.
- inversion H4. eapply make_binop_correct; eauto with cshm.
+ inversion H4. econstructor; eauto with cshm.
inversion H4. eauto with cshm.
Qed.
@@ -186,21 +165,21 @@ Proof.
Qed.
Definition binary_constructor_correct
- (make: expr -> type -> expr -> type -> option expr)
+ (make: expr -> type -> expr -> type -> res expr)
(sem: val -> type -> val -> type -> option val): Prop :=
forall a tya b tyb c ta va tb vb v le e m1 m2 m3,
sem va tya vb tyb = Some v ->
- make a tya b tyb = Some c ->
+ make a tya b tyb = OK c ->
eval_expr tprog le e m1 a ta m2 va ->
eval_expr tprog le e m2 b tb m3 vb ->
eval_expr tprog le e m1 c (ta ** tb) m3 v.
Definition binary_constructor_correct'
- (make: expr -> type -> expr -> type -> option expr)
+ (make: expr -> type -> expr -> type -> res expr)
(sem: val -> val -> option val): Prop :=
forall a tya b tyb c ta va tb vb v le e m1 m2 m3,
sem va vb = Some v ->
- make a tya b tyb = Some c ->
+ make a tya b tyb = OK c ->
eval_expr tprog le e m1 a ta m2 va ->
eval_expr tprog le e m2 b tb m3 vb ->
eval_expr tprog le e m1 c (ta ** tb) m3 v.
@@ -212,8 +191,8 @@ Proof.
inversion H7. eauto with cshm.
inversion H7. eauto with cshm.
inversion H7.
- eapply make_binop_correct. eauto.
- eapply make_binop_correct. eauto with cshm. eauto.
+ econstructor. eauto.
+ econstructor. eauto with cshm. eauto.
simpl. reflexivity. reflexivity.
simpl. reflexivity. traceEq.
Qed.
@@ -223,12 +202,12 @@ Proof.
red; intros until m3. intro SEM. unfold make_sub.
functional inversion SEM; rewrite H0; intros;
inversion H7; eauto with cshm.
- eapply make_binop_correct. eauto.
- eapply make_binop_correct. eauto with cshm. eauto.
+ econstructor. eauto.
+ econstructor. eauto with cshm. eauto.
simpl. reflexivity. reflexivity.
simpl. reflexivity. traceEq.
- inversion H9. eapply make_binop_correct.
- eapply make_binop_correct; eauto.
+ inversion H9. econstructor.
+ econstructor; eauto.
simpl. unfold eq_block; rewrite H3. reflexivity.
eauto with cshm. simpl. rewrite H8. reflexivity. traceEq.
Qed.
@@ -244,9 +223,9 @@ Lemma make_div_correct: binary_constructor_correct make_div sem_div.
Proof.
red; intros until m3. intro SEM. unfold make_div.
functional inversion SEM; rewrite H0; intros.
- inversion H8. eapply make_binop_correct; eauto with cshm.
+ inversion H8. econstructor; eauto with cshm.
simpl. rewrite H7; auto.
- inversion H8. eapply make_binop_correct; eauto with cshm.
+ inversion H8. econstructor; eauto with cshm.
simpl. rewrite H7; auto.
inversion H7; eauto with cshm.
Qed.
@@ -254,9 +233,9 @@ Qed.
Lemma make_mod_correct: binary_constructor_correct make_mod sem_mod.
red; intros until m3. intro SEM. unfold make_mod.
functional inversion SEM; rewrite H0; intros.
- inversion H8. eapply make_binop_correct; eauto with cshm.
+ inversion H8. econstructor; eauto with cshm.
simpl. rewrite H7; auto.
- inversion H8. eapply make_binop_correct; eauto with cshm.
+ inversion H8. econstructor; eauto with cshm.
simpl. rewrite H7; auto.
Qed.
@@ -285,7 +264,7 @@ Lemma make_shl_correct: binary_constructor_correct' make_shl sem_shl.
Proof.
red; intros until m3. intro SEM. unfold make_shl.
functional inversion SEM. intros. inversion H5.
- eapply make_binop_correct; eauto with cshm.
+ econstructor; eauto with cshm.
simpl. rewrite H4. auto.
Qed.
@@ -293,16 +272,16 @@ Lemma make_shr_correct: binary_constructor_correct make_shr sem_shr.
Proof.
red; intros until m3. intro SEM. unfold make_shr.
functional inversion SEM; intros; rewrite H0 in H8; inversion H8.
- eapply make_binop_correct; eauto with cshm.
+ econstructor; eauto with cshm.
simpl; rewrite H7; auto.
- eapply make_binop_correct; eauto with cshm.
+ econstructor; eauto with cshm.
simpl; rewrite H7; auto.
Qed.
Lemma make_cmp_correct:
forall cmp a tya b tyb c ta va tb vb v le e m1 m2 m3,
sem_cmp cmp va tya vb tyb m3 = Some v ->
- make_cmp cmp a tya b tyb = Some c ->
+ make_cmp cmp a tya b tyb = OK c ->
eval_expr tprog le e m1 a ta m2 va ->
eval_expr tprog le e m2 b tb m3 vb ->
eval_expr tprog le e m1 c (ta ** tb) m3 v.
@@ -312,16 +291,16 @@ Proof.
inversion H8. eauto with cshm.
inversion H8. eauto with cshm.
inversion H8. eauto with cshm.
- inversion H9. eapply make_binop_correct; eauto with cshm.
+ inversion H9. econstructor; eauto with cshm.
simpl. functional inversion H; subst; unfold eval_compare_null;
rewrite H8; auto.
- inversion H10. eapply make_binop_correct; eauto with cshm.
+ inversion H10. econstructor; eauto with cshm.
simpl. rewrite H3. unfold eq_block; rewrite H9. auto.
Qed.
Lemma transl_unop_correct:
forall op a tya c ta va v le e m1 m2,
- transl_unop op a tya = Some c ->
+ transl_unop op a tya = OK c ->
sem_unary_operation op va tya = Some v ->
eval_expr tprog le e m1 a ta m2 va ->
eval_expr tprog le e m1 c ta m2 v.
@@ -334,7 +313,7 @@ Qed.
Lemma transl_binop_correct:
forall op a tya b tyb c ta va tb vb v le e m1 m2 m3,
- transl_binop op a tya b tyb = Some c ->
+ transl_binop op a tya b tyb = OK c ->
sem_binary_operation op va tya vb tyb m3 = Some v ->
eval_expr tprog le e m1 a ta m2 va ->
eval_expr tprog le e m2 b tb m3 vb ->
@@ -365,7 +344,7 @@ Lemma make_cast_correct:
cast v ty1 ty2 v' ->
eval_expr tprog le e m1 (make_cast ty1 ty2 a) t m2 v'.
Proof.
- unfold make_cast, make_cast1, make_cast2, make_unop.
+ unfold make_cast, make_cast1, make_cast2.
intros until v'; intros EVAL CAST.
inversion CAST; clear CAST; subst.
(* cast_int_int *)
@@ -373,7 +352,7 @@ Proof.
(* cast_float_int *)
destruct sz2; destruct si2; repeat econstructor; eauto with cshm; simpl; auto.
(* cast_int_float *)
- destruct sz2; destruct si1; unfold make_floatofint, make_unop; repeat econstructor; eauto with cshm; simpl; auto.
+ destruct sz2; destruct si1; unfold make_floatofint; repeat econstructor; eauto with cshm; simpl; auto.
(* cast_float_float *)
destruct sz2; repeat econstructor; eauto with cshm.
(* neutral, ptr *)
@@ -384,7 +363,7 @@ Qed.
Lemma make_load_correct:
forall addr ty code b ofs v le e m1 t m2,
- make_load addr ty = Some code ->
+ make_load addr ty = OK code ->
eval_expr tprog le e m1 addr t m2 (Vptr b ofs) ->
load_value_of_type ty m2 b ofs = Some v ->
eval_expr tprog le e m1 code t m2 v.
@@ -400,7 +379,7 @@ Qed.
Lemma make_store_correct:
forall addr ty rhs code e m1 t1 m2 b ofs t2 m3 v m4,
- make_store addr ty rhs = Some code ->
+ make_store addr ty rhs = OK code ->
eval_expr tprog nil e m1 addr t1 m2 (Vptr b ofs) ->
eval_expr tprog nil e m2 rhs t2 m3 v ->
store_value_of_type ty m3 b ofs v = Some m4 ->
diff --git a/cfrontend/Cshmgenproof3.v b/cfrontend/Cshmgenproof3.v
index 497286b..c8b9caf 100644
--- a/cfrontend/Cshmgenproof3.v
+++ b/cfrontend/Cshmgenproof3.v
@@ -1,6 +1,7 @@
(** * Correctness of the C front end, part 3: semantic preservation *)
Require Import Coqlib.
+Require Import Errors.
Require Import Maps.
Require Import Integers.
Require Import Floats.
@@ -12,6 +13,7 @@ Require Import Globalenvs.
Require Import Csyntax.
Require Import Csem.
Require Import Ctyping.
+Require Import Cminor.
Require Import Csharpminor.
Require Import Cshmgen.
Require Import Cshmgenproof1.
@@ -22,40 +24,26 @@ Section CORRECTNESS.
Variable prog: Csyntax.program.
Variable tprog: Csharpminor.program.
Hypothesis WTPROG: wt_program prog.
-Hypothesis TRANSL: transl_program prog = Some tprog.
+Hypothesis TRANSL: transl_program prog = OK tprog.
Let ge := Genv.globalenv prog.
Let tge := Genv.globalenv tprog.
Lemma symbols_preserved:
forall s, Genv.find_symbol tge s = Genv.find_symbol ge s.
-Proof.
- intros. unfold ge, tge.
- apply Genv.find_symbol_transf_partial2 with transl_fundef transl_globvar.
- auto.
-Qed.
+Proof (Genv.find_symbol_transf_partial2 transl_fundef transl_globvar _ TRANSL).
Lemma functions_translated:
forall v f,
Genv.find_funct ge v = Some f ->
- exists tf, Genv.find_funct tge v = Some tf /\ transl_fundef f = Some tf.
-Proof.
- intros.
- generalize (Genv.find_funct_transf_partial2 transl_fundef transl_globvar TRANSL H).
- intros [A B].
- destruct (transl_fundef f). exists f0; split. assumption. auto. congruence.
-Qed.
+ exists tf, Genv.find_funct tge v = Some tf /\ transl_fundef f = OK tf.
+Proof (Genv.find_funct_transf_partial2 transl_fundef transl_globvar TRANSL).
Lemma function_ptr_translated:
forall b f,
Genv.find_funct_ptr ge b = Some f ->
- exists tf, Genv.find_funct_ptr tge b = Some tf /\ transl_fundef f = Some tf.
-Proof.
- intros.
- generalize (Genv.find_funct_ptr_transf_partial2 transl_fundef transl_globvar TRANSL H).
- intros [A B].
- destruct (transl_fundef f). exists f0; split. assumption. auto. congruence.
-Qed.
+ exists tf, Genv.find_funct_ptr tge b = Some tf /\ transl_fundef f = OK tf.
+Proof (Genv.find_funct_ptr_transf_partial2 transl_fundef transl_globvar TRANSL).
Lemma functions_well_typed:
forall v f,
@@ -119,7 +107,7 @@ Proof.
Qed.
Lemma match_var_kind_of_type:
- forall ty vk, var_kind_of_type ty = Some vk -> match_var_kind ty vk.
+ forall ty vk, var_kind_of_type ty = OK vk -> match_var_kind ty vk.
Proof.
intros; red.
caseEq (access_mode ty); auto.
@@ -131,7 +119,7 @@ Lemma match_env_alloc_variables:
Csem.alloc_variables e1 m1 vars e2 m2 lb ->
forall tyenv te1 tvars,
match_env tyenv e1 te1 ->
- transl_vars vars = Some tvars ->
+ transl_vars vars = OK tvars ->
exists te2,
Csharpminor.alloc_variables te1 m1 tvars te2 m2 lb
/\ match_env (Ctyping.add_vars tyenv vars) e2 te2.
@@ -140,8 +128,8 @@ Proof.
simpl in H0. inversion H0; subst; clear H0.
exists te1; split. constructor. simpl. auto.
generalize H2. simpl.
- caseEq (var_kind_of_type ty); [intros vk VK | congruence].
- caseEq (transl_vars vars); [intros tvrs TVARS | congruence].
+ caseEq (var_kind_of_type ty); simpl; [intros vk VK | congruence].
+ caseEq (transl_vars vars); simpl; [intros tvrs TVARS | congruence].
intro EQ; inversion EQ; subst tvars; clear EQ.
set (te2 := PTree.set id (b1, vk) te1).
assert (match_env (add_var tyenv (id, ty)) (PTree.set id b1 e) te2).
@@ -168,14 +156,14 @@ Lemma bind_parameters_match_rec:
forall tyenv te tvars,
(forall id ty, In (id, ty) vars -> tyenv!id = Some ty) ->
match_env tyenv e te ->
- transl_params vars = Some tvars ->
+ transl_params vars = OK tvars ->
Csharpminor.bind_parameters te m1 tvars vals m2.
Proof.
induction 1; intros.
simpl in H1. inversion H1. constructor.
generalize H4; clear H4; simpl.
- caseEq (chunk_of_type ty); [intros chunk CHK | congruence].
- caseEq (transl_params params); [intros tparams TPARAMS | congruence].
+ caseEq (chunk_of_type ty); simpl; [intros chunk CHK | congruence].
+ caseEq (transl_params params); simpl; [intros tparams TPARAMS | congruence].
intro EQ; inversion EQ; clear EQ; subst tvars.
generalize CHK. unfold chunk_of_type.
caseEq (access_mode ty); intros; try discriminate.
@@ -215,7 +203,7 @@ Lemma bind_parameters_match:
Csem.bind_parameters e m1 params vals m2 ->
list_norepet (var_names params ++ var_names vars) ->
match_env (Ctyping.add_vars tyenv (params ++ vars)) e te ->
- transl_params params = Some tvars ->
+ transl_params params = OK tvars ->
Csharpminor.bind_parameters te m1 tvars vals m2.
Proof.
intros.
@@ -273,14 +261,14 @@ Qed.
Lemma add_global_var_match_globalenv:
forall vars tenv gv tvars,
match_globalenv tenv gv ->
- map_partial transl_globvar vars = Some tvars ->
+ map_partial AST.prefix_var_name transl_globvar vars = OK tvars ->
match_globalenv (add_global_vars tenv vars) (globvarenv gv tvars).
Proof.
induction vars; simpl.
intros. inversion H0. assumption.
destruct a as [[id init] ty]. intros until tvars; intro.
- caseEq (transl_globvar ty); try congruence. intros vk VK.
- caseEq (map_partial transl_globvar vars); try congruence. intros tvars' EQ1 EQ2.
+ caseEq (transl_globvar ty); simpl; try congruence. intros vk VK.
+ caseEq (map_partial AST.prefix_var_name transl_globvar vars); simpl; try congruence. intros tvars' EQ1 EQ2.
inversion EQ2; clear EQ2. simpl.
apply IHvars; auto.
red. intros until chunk. repeat rewrite PTree.gsspec.
@@ -299,7 +287,7 @@ Proof.
unfold global_typenv.
apply add_global_var_match_globalenv.
apply add_global_funs_match_global_env.
- unfold transl_program in TRANSL. functional inversion TRANSL. auto.
+ unfold transl_program in TRANSL. monadInv TRANSL. auto.
Qed.
(** ** Variable accessors *)
@@ -309,7 +297,7 @@ Lemma var_get_correct:
Csem.eval_lvalue ge e m (Expr (Csyntax.Evar id) ty) E0 m loc ofs ->
load_value_of_type ty m loc ofs = Some v ->
wt_expr tyenv (Expr (Csyntax.Evar id) ty) ->
- var_get id ty = Some code ->
+ var_get id ty = OK code ->
match_env tyenv e te ->
eval_expr tprog le te m code E0 m v.
Proof.
@@ -356,7 +344,7 @@ Lemma var_set_correct:
Csem.eval_lvalue ge e m (Expr (Csyntax.Evar id) ty) t1 m1 loc ofs ->
store_value_of_type ty m2 loc ofs v = Some m3 ->
wt_expr tyenv (Expr (Csyntax.Evar id) ty) ->
- var_set id ty rhs = Some code ->
+ var_set id ty rhs = OK code ->
match_env tyenv e te ->
eval_expr tprog nil te m1 rhs t2 m2 v ->
exec_stmt tprog te m code (t1 ** t2) m3 Out_normal.
@@ -394,7 +382,7 @@ Definition eval_expr_prop
(e: Csem.env) (m1: mem) (a: Csyntax.expr) (t: trace) (m2: mem) (v: val) : Prop :=
forall tyenv ta te tle
(WT: wt_expr tyenv a)
- (TR: transl_expr a = Some ta)
+ (TR: transl_expr a = OK ta)
(MENV: match_env tyenv e te),
Csharpminor.eval_expr tprog tle te m1 ta t m2 v.
@@ -403,7 +391,7 @@ Definition eval_lvalue_prop
(m2: mem) (b: block) (ofs: int) : Prop :=
forall tyenv ta te tle
(WT: wt_expr tyenv a)
- (TR: transl_lvalue a = Some ta)
+ (TR: transl_lvalue a = OK ta)
(MENV: match_env tyenv e te),
Csharpminor.eval_expr tprog tle te m1 ta t m2 (Vptr b ofs).
@@ -412,7 +400,7 @@ Definition eval_exprlist_prop
(m2: mem) (vl: list val) : Prop :=
forall tyenv tal te tle
(WT: wt_exprlist tyenv al)
- (TR: transl_exprlist al = Some tal)
+ (TR: transl_exprlist al = OK tal)
(MENV: match_env tyenv e te),
Csharpminor.eval_exprlist tprog tle te m1 tal t m2 vl.
@@ -429,7 +417,7 @@ Definition exec_stmt_prop
(m2: mem) (out: Csem.outcome) : Prop :=
forall tyenv nbrk ncnt ts te
(WT: wt_stmt tyenv s)
- (TR: transl_statement nbrk ncnt s = Some ts)
+ (TR: transl_statement nbrk ncnt s = OK ts)
(MENV: match_env tyenv e te),
Csharpminor.exec_stmt tprog te m1 ts t m2 (transl_outcome nbrk ncnt out).
@@ -440,7 +428,7 @@ Definition exec_lblstmts_prop
(WT: wt_lblstmts tyenv s)
(TR: transl_lblstmts (lblstmts_length s)
(1 + lblstmts_length s + ncnt)
- s body = Some ts)
+ s body = OK ts)
(MENV: match_env tyenv e te)
(BODY: Csharpminor.exec_stmt tprog te m0 body t0 m1 Out_normal),
Csharpminor.exec_stmt tprog te m0 ts (t0 ** t) m2
@@ -451,7 +439,7 @@ Definition eval_funcall_prop
(t: trace) (m2: mem) (res: val) : Prop :=
forall tf
(WT: wt_fundef (global_typenv prog) f)
- (TR: transl_fundef f = Some tf),
+ (TR: transl_fundef f = OK tf),
Csharpminor.eval_funcall tprog m1 tf params t m2 res.
(*
@@ -465,7 +453,7 @@ Lemma transl_Econst_int_correct:
eval_expr_prop e m (Expr (Econst_int i) ty) E0 m (Vint i)).
Proof.
intros; red; intros.
- monadInv TR. subst ta. apply make_intconst_correct.
+ monadInv TR. apply make_intconst_correct.
Qed.
Lemma transl_Econst_float_correct:
@@ -473,7 +461,7 @@ Lemma transl_Econst_float_correct:
eval_expr_prop e m (Expr (Econst_float f0) ty) E0 m (Vfloat f0)).
Proof.
intros; red; intros.
- monadInv TR. subst ta. apply make_floatconst_correct.
+ monadInv TR. apply make_floatconst_correct.
Qed.
Lemma transl_Elvalue_correct:
@@ -512,16 +500,16 @@ Lemma transl_Esizeof_correct:
eval_expr_prop e m (Expr (Esizeof ty') ty) E0 m
(Vint (Int.repr (Csyntax.sizeof ty')))).
Proof.
- intros; red; intros. monadInv TR. subst ta. apply make_intconst_correct.
+ intros; red; intros. monadInv TR. apply make_intconst_correct.
Qed.
Lemma transl_Eunop_correct:
- (forall (e : Csem.env) (m : mem) (op : unary_operation)
+ (forall (e : Csem.env) (m : mem) (op : Csyntax.unary_operation)
(a : Csyntax.expr) (ty : type) (t : trace) (m1 : mem) (v1 v : val),
Csem.eval_expr ge e m a t m1 v1 ->
eval_expr_prop e m a t m1 v1 ->
sem_unary_operation op v1 (typeof a) = Some v ->
- eval_expr_prop e m (Expr (Eunop op a) ty) t m1 v).
+ eval_expr_prop e m (Expr (Csyntax.Eunop op a) ty) t m1 v).
Proof.
intros; red; intros.
inversion WT; clear WT; subst.
@@ -530,7 +518,7 @@ Proof.
Qed.
Lemma transl_Ebinop_correct:
- (forall (e : Csem.env) (m : mem) (op : binary_operation)
+ (forall (e : Csem.env) (m : mem) (op : Csyntax.binary_operation)
(a1 a2 : Csyntax.expr) (ty : type) (t1 : trace) (m1 : mem)
(v1 : val) (t2 : trace) (m2 : mem) (v2 v : val),
Csem.eval_expr ge e m a1 t1 m1 v1 ->
@@ -538,7 +526,7 @@ Lemma transl_Ebinop_correct:
Csem.eval_expr ge e m1 a2 t2 m2 v2 ->
eval_expr_prop e m1 a2 t2 m2 v2 ->
sem_binary_operation op v1 (typeof a1) v2 (typeof a2) m2 = Some v ->
- eval_expr_prop e m (Expr (Ebinop op a1 a2) ty) (t1 ** t2) m2 v).
+ eval_expr_prop e m (Expr (Csyntax.Ebinop op a1 a2) ty) (t1 ** t2) m2 v).
Proof.
intros; red; intros.
inversion WT; clear WT; subst.
@@ -555,7 +543,7 @@ Lemma transl_Eorbool_1_correct:
eval_expr_prop e m (Expr (Eorbool a1 a2) ty) t m1 Vtrue).
Proof.
intros; red; intros. inversion WT; clear WT; subst. monadInv TR.
- rewrite <- H3; unfold make_orbool.
+ unfold make_orbool.
exploit make_boolean_correct_true; eauto. intros [vb [EVAL ISTRUE]].
eapply eval_Econdition_true; eauto.
unfold Vtrue; apply make_intconst_correct. traceEq.
@@ -574,7 +562,7 @@ Lemma transl_Eorbool_2_correct:
eval_expr_prop e m (Expr (Eorbool a1 a2) ty) (t1 ** t2) m2 v).
Proof.
intros; red; intros. inversion WT; clear WT; subst. monadInv TR.
- rewrite <- H6; unfold make_orbool.
+ unfold make_orbool.
exploit make_boolean_correct_false. eapply H0; eauto. eauto. intros [vb [EVAL ISFALSE]].
eapply eval_Econdition_false; eauto.
inversion H4; subst.
@@ -595,7 +583,7 @@ Lemma transl_Eandbool_1_correct:
eval_expr_prop e m (Expr (Eandbool a1 a2) ty) t m1 Vfalse).
Proof.
intros; red; intros. inversion WT; clear WT; subst. monadInv TR.
- rewrite <- H3; unfold make_andbool.
+ unfold make_andbool.
exploit make_boolean_correct_false; eauto. intros [vb [EVAL ISFALSE]].
eapply eval_Econdition_false; eauto.
unfold Vfalse; apply make_intconst_correct. traceEq.
@@ -614,7 +602,7 @@ Lemma transl_Eandbool_2_correct:
eval_expr_prop e m (Expr (Eandbool a1 a2) ty) (t1 ** t2) m2 v).
Proof.
intros; red; intros. inversion WT; clear WT; subst. monadInv TR.
- rewrite <- H6; unfold make_andbool.
+ unfold make_andbool.
exploit make_boolean_correct_true. eapply H0; eauto. eauto. intros [vb [EVAL ISTRUE]].
eapply eval_Econdition_true; eauto.
inversion H4; subst.
@@ -634,7 +622,7 @@ Lemma transl_Ecast_correct:
cast v1 (typeof a) ty v ->
eval_expr_prop e m (Expr (Ecast ty a) ty) t m1 v).
Proof.
- intros; red; intros. inversion WT; clear WT; subst. monadInv TR. subst ta.
+ intros; red; intros. inversion WT; clear WT; subst. monadInv TR.
eapply make_cast_correct; eauto.
Qed.
@@ -660,7 +648,7 @@ Proof.
caseEq (classify_fun (typeof a)).
2: intros; rewrite H7 in TR; discriminate.
intros targs tres EQ. rewrite EQ in TR.
- monadInv TR. clear TR. subst ta.
+ monadInv TR.
rewrite <- H4 in EQ.
exploit functions_translated; eauto. intros [tf [FIND TRL]].
econstructor.
@@ -679,7 +667,7 @@ Lemma transl_Evar_local_correct:
e ! id = Some l ->
eval_lvalue_prop e m (Expr (Csyntax.Evar id) ty) E0 m l Int.zero).
Proof.
- intros; red; intros. inversion WT; clear WT; subst. monadInv TR. subst ta.
+ intros; red; intros. inversion WT; clear WT; subst. monadInv TR.
exploit (me_local _ _ _ MENV); eauto. intros [vk [A B]].
econstructor. eapply eval_var_addr_local. eauto.
Qed.
@@ -691,7 +679,7 @@ Lemma transl_Evar_global_correct:
Genv.find_symbol ge id = Some l ->
eval_lvalue_prop e m (Expr (Csyntax.Evar id) ty) E0 m l Int.zero).
Proof.
- intros; red; intros. inversion WT; clear WT; subst. monadInv TR. subst ta.
+ intros; red; intros. inversion WT; clear WT; subst. monadInv TR.
exploit (me_global _ _ _ MENV); eauto. intros [A B].
econstructor. eapply eval_var_addr_global. eauto.
rewrite symbols_preserved. auto.
@@ -730,13 +718,13 @@ Lemma transl_Efield_struct_correct:
eval_lvalue ge e m a t m1 l ofs ->
eval_lvalue_prop e m a t m1 l ofs ->
typeof a = Tstruct id fList ->
- field_offset i fList = Some delta ->
+ field_offset i fList = OK delta ->
eval_lvalue_prop e m (Expr (Efield a i) ty) t m1 l
(Int.add ofs (Int.repr delta))).
Proof.
intros; red; intros. inversion WT; clear WT; subst.
simpl in TR. rewrite H1 in TR. monadInv TR.
- rewrite <- H5. eapply make_binop_correct; eauto.
+ econstructor; eauto.
apply make_intconst_correct.
simpl. congruence. traceEq.
Qed.
@@ -758,7 +746,7 @@ Lemma transl_Enil_correct:
(forall (e : Csem.env) (m : mem),
eval_exprlist_prop e m Csyntax.Enil E0 m nil).
Proof.
- intros; red; intros. monadInv TR. subst tal. constructor.
+ intros; red; intros. monadInv TR. constructor.
Qed.
Lemma transl_Econs_correct:
@@ -772,14 +760,14 @@ Lemma transl_Econs_correct:
eval_exprlist_prop e m (Csyntax.Econs a bl) (t1 ** t2) m2 (v :: vl)).
Proof.
intros; red; intros. inversion WT; clear WT; subst. simpl in TR; monadInv TR.
- subst tal. econstructor; eauto.
+ econstructor; eauto.
Qed.
Lemma transl_Sskip_correct:
(forall (e : Csem.env) (m : mem),
exec_stmt_prop e m Csyntax.Sskip E0 m Csem.Out_normal).
Proof.
- intros; red; intros. monadInv TR. subst ts. simpl. constructor.
+ intros; red; intros. monadInv TR. simpl. constructor.
Qed.
Lemma transl_Sexpr_correct:
@@ -790,8 +778,7 @@ Lemma transl_Sexpr_correct:
exec_stmt_prop e m (Csyntax.Sexpr a) t m1 Csem.Out_normal).
Proof.
intros; red; intros; simpl. inversion WT; clear WT; subst.
- monadInv TR. subst ts.
- econstructor; eauto.
+ monadInv TR. econstructor; eauto.
Qed.
Lemma transl_Sassign_correct:
@@ -831,7 +818,7 @@ Lemma transl_Ssequence_1_correct:
exec_stmt_prop e m (Ssequence s1 s2) (t1 ** t2) m2 out).
Proof.
intros; red; intros. inversion WT; clear WT; subst. simpl in TR; monadInv TR.
- subst ts. red in H0; simpl in H0. eapply exec_Sseq_continue; eauto.
+ red in H0; simpl in H0. eapply exec_Sseq_continue; eauto.
Qed.
Lemma transl_Ssequence_2_correct:
@@ -843,7 +830,7 @@ Lemma transl_Ssequence_2_correct:
exec_stmt_prop e m (Ssequence s1 s2) t1 m1 out).
Proof.
intros; red; intros. inversion WT; clear WT; subst. simpl in TR; monadInv TR.
- subst ts. eapply exec_Sseq_stop; eauto.
+ eapply exec_Sseq_stop; eauto.
destruct out; simpl; congruence.
Qed.
@@ -860,7 +847,7 @@ Lemma transl_Sifthenelse_true_correct:
Proof.
intros; red; intros. inversion WT; clear WT; subst. simpl in TR; monadInv TR.
exploit make_boolean_correct_true. eapply H0; eauto. eauto. intros [vb [EVAL ISTRUE]].
- subst ts. eapply exec_Sifthenelse_true; eauto.
+ eapply exec_Sifthenelse_true; eauto.
Qed.
Lemma transl_Sifthenelse_false_correct:
@@ -876,7 +863,7 @@ Lemma transl_Sifthenelse_false_correct:
Proof.
intros; red; intros. inversion WT; clear WT; subst. simpl in TR; monadInv TR.
exploit make_boolean_correct_false. eapply H0; eauto. eauto. intros [vb [EVAL ISFALSE]].
- subst ts. eapply exec_Sifthenelse_false; eauto.
+ eapply exec_Sifthenelse_false; eauto.
Qed.
Lemma transl_Sreturn_none_correct:
@@ -884,7 +871,7 @@ Lemma transl_Sreturn_none_correct:
exec_stmt_prop e m (Csyntax.Sreturn None) E0 m (Csem.Out_return None)).
Proof.
intros; red; intros. inversion WT; clear WT; subst. simpl in TR; monadInv TR.
- subst ts. simpl. apply exec_Sreturn_none.
+ simpl. apply exec_Sreturn_none.
Qed.
Lemma transl_Sreturn_some_correct:
@@ -896,7 +883,7 @@ Lemma transl_Sreturn_some_correct:
(Csem.Out_return (Some v))).
Proof.
intros; red; intros. inversion WT; clear WT; subst. simpl in TR; monadInv TR.
- subst ts. simpl. eapply exec_Sreturn_some; eauto.
+ simpl. eapply exec_Sreturn_some; eauto.
Qed.
Lemma transl_Sbreak_correct:
@@ -904,7 +891,7 @@ Lemma transl_Sbreak_correct:
exec_stmt_prop e m Sbreak E0 m Out_break).
Proof.
intros; red; intros. inversion WT; clear WT; subst. simpl in TR; monadInv TR.
- subst ts. simpl. apply exec_Sexit.
+ simpl. apply exec_Sexit.
Qed.
Lemma transl_Scontinue_correct:
@@ -912,19 +899,19 @@ Lemma transl_Scontinue_correct:
exec_stmt_prop e m Scontinue E0 m Out_continue).
Proof.
intros; red; intros. inversion WT; clear WT; subst. simpl in TR; monadInv TR.
- subst ts. simpl. apply exec_Sexit.
+ simpl. apply exec_Sexit.
Qed.
Lemma exit_if_false_true:
forall a ts e m1 t m2 v tyenv te,
- exit_if_false a = Some ts ->
+ exit_if_false a = OK ts ->
eval_expr_prop e m1 a t m2 v ->
match_env tyenv e te ->
wt_expr tyenv a ->
is_true v (typeof a) ->
exec_stmt tprog te m1 ts t m2 Out_normal.
Proof.
- intros. monadInv H. rewrite <- H5.
+ intros. monadInv H.
exploit make_boolean_correct_true. eapply H0; eauto. eauto.
intros [vb [EVAL ISTRUE]].
eapply exec_Sifthenelse_true with (v1 := vb); eauto.
@@ -933,14 +920,14 @@ Qed.
Lemma exit_if_false_false:
forall a ts e m1 t m2 v tyenv te,
- exit_if_false a = Some ts ->
+ exit_if_false a = OK ts ->
eval_expr_prop e m1 a t m2 v ->
match_env tyenv e te ->
wt_expr tyenv a ->
is_false v (typeof a) ->
exec_stmt tprog te m1 ts t m2 (Out_exit 0).
Proof.
- intros. monadInv H. rewrite <- H5.
+ intros. monadInv H.
exploit make_boolean_correct_false. eapply H0; eauto. eauto.
intros [vb [EVAL ISFALSE]].
eapply exec_Sifthenelse_false with (v1 := vb); eauto.
@@ -956,7 +943,7 @@ Lemma transl_Swhile_false_correct:
exec_stmt_prop e m (Swhile a s) t m1 Csem.Out_normal).
Proof.
intros; red; intros. inversion WT; clear WT; subst. simpl in TR; monadInv TR.
- subst ts. simpl.
+ simpl.
change Out_normal with (outcome_block (Out_exit 0)).
apply exec_Sblock. apply exec_Sloop_stop. apply exec_Sseq_stop.
eapply exit_if_false_false; eauto. congruence. congruence.
@@ -992,7 +979,7 @@ Lemma transl_Swhile_stop_correct:
exec_stmt_prop e m (Swhile a s) (t1 ** t2) m2 out).
Proof.
intros; red; intros. inversion WT; clear WT; subst. simpl in TR; monadInv TR.
- subst ts. rewrite (transl_out_break_or_return _ _ nbrk ncnt H4).
+ rewrite (transl_out_break_or_return _ _ nbrk ncnt H4).
apply exec_Sblock. apply exec_Sloop_stop.
eapply exec_Sseq_continue.
eapply exit_if_false_true; eauto.
@@ -1017,7 +1004,6 @@ Proof.
intros; red; intros.
exploit H6; eauto. intro NEXTITER.
inversion WT; clear WT; subst. simpl in TR; monadInv TR.
- subst ts.
inversion NEXTITER; subst.
apply exec_Sblock.
eapply exec_Sloop_loop. eapply exec_Sseq_continue.
@@ -1041,7 +1027,7 @@ Lemma transl_Sdowhile_false_correct:
exec_stmt_prop e m (Sdowhile a s) (t1 ** t2) m2 Csem.Out_normal).
Proof.
intros; red; intros. inversion WT; clear WT; subst. simpl in TR; monadInv TR.
- subst ts. simpl.
+ simpl.
change Out_normal with (outcome_block (Out_exit 0)).
apply exec_Sblock. apply exec_Sloop_stop. eapply exec_Sseq_continue.
rewrite (transl_out_normal_or_continue out1 H1).
@@ -1058,7 +1044,7 @@ Lemma transl_Sdowhile_stop_correct:
exec_stmt_prop e m (Sdowhile a s) t m1 out).
Proof.
intros; red; intros. inversion WT; clear WT; subst. simpl in TR; monadInv TR.
- subst ts. simpl.
+ simpl.
assert (outcome_block (transl_outcome 1 0 out1) <> Out_normal).
inversion H1; simpl; congruence.
rewrite (transl_out_break_or_return _ _ nbrk ncnt H1).
@@ -1084,7 +1070,6 @@ Proof.
intros; red; intros.
exploit H6; eauto. intro NEXTITER.
inversion WT; clear WT; subst. simpl in TR; monadInv TR.
- subst ts.
inversion NEXTITER; subst.
apply exec_Sblock.
eapply exec_Sloop_loop. eapply exec_Sseq_continue.
@@ -1129,7 +1114,7 @@ Lemma transl_Sfor_false_correct:
exec_stmt_prop e m (Sfor Csyntax.Sskip a2 a3 s) t m1 Csem.Out_normal).
Proof.
intros; red; intros. inversion WT; clear WT; subst. simpl in TR; monadInv TR.
- subst ts. simpl.
+ simpl.
eapply exec_Sseq_continue. apply exec_Sskip.
change Out_normal with (outcome_block (Out_exit 0)).
apply exec_Sblock. apply exec_Sloop_stop.
@@ -1150,7 +1135,7 @@ Lemma transl_Sfor_stop_correct:
exec_stmt_prop e m (Sfor Csyntax.Sskip a2 a3 s) (t1 ** t2) m2 out).
Proof.
intros; red; intros. inversion WT; clear WT; subst. simpl in TR; monadInv TR.
- subst ts. simpl.
+ simpl.
assert (outcome_block (transl_outcome 1 0 out2) <> Out_normal).
inversion H4; simpl; congruence.
rewrite (transl_out_break_or_return _ _ nbrk ncnt H4).
@@ -1181,7 +1166,6 @@ Proof.
intros; red; intros.
exploit H8; eauto. intro NEXTITER.
inversion WT; clear WT; subst. simpl in TR; monadInv TR.
- subst ts.
inversion NEXTITER; subst.
inversion H11; subst.
inversion H18; subst.
@@ -1205,7 +1189,7 @@ Lemma transl_lblstmts_switch:
transl_lblstmts
(lblstmts_length sl)
(S (lblstmts_length sl + ncnt))
- sl (Sblock body) = Some ts ->
+ sl (Sblock body) = OK ts ->
wt_lblstmts tyenv sl ->
match_env tyenv e te ->
exec_lblstmts_prop e m1 (select_switch n sl) t2 m2 out ->
@@ -1226,7 +1210,7 @@ Proof.
(* next case selected *)
inversion H1; clear H1; subst.
simpl in H0; monadInv H0.
- eapply IHsl with (body := Sseq (Sblock body) s0); eauto.
+ eapply IHsl with (body := Sseq (Sblock body) x); eauto.
apply exec_Sseq_stop.
change (Out_exit (switch_target n (lblstmts_length sl) (switch_table sl 0)))
with (outcome_block (Out_exit (S (switch_target n (lblstmts_length sl) (switch_table sl 0))))).
@@ -1247,7 +1231,7 @@ Lemma transl_Sswitch_correct:
Proof.
intros; red; intros.
inversion WT; clear WT; subst.
- simpl in TR. monadInv TR; clear TR.
+ simpl in TR. monadInv TR.
rewrite length_switch_table in EQ0.
replace (ncnt + lblstmts_length sl + 1)%nat
with (S (lblstmts_length sl + ncnt))%nat in EQ0 by omega.
@@ -1265,7 +1249,6 @@ Proof.
intros; red; intros.
inversion WT; subst.
simpl in TR. monadInv TR.
- rewrite <- H3.
replace (transl_outcome nbrk ncnt (outcome_switch out))
with (outcome_block (transl_outcome 0 (S ncnt) out)).
constructor.
@@ -1286,8 +1269,8 @@ Lemma transl_LScase_fallthrough_correct:
Proof.
intros; red; intros.
inversion WT; subst.
- simpl in TR. monadInv TR; clear TR.
- assert (exec_stmt tprog te m0 (Sblock (Sseq body s0))
+ monadInv TR.
+ assert (exec_stmt tprog te m0 (Sblock (Sseq body x))
(t0 ** t1) m1 Out_normal).
change Out_normal with
(outcome_block (transl_outcome (S (lblstmts_length ls))
@@ -1311,19 +1294,19 @@ Lemma transl_LScase_stop_correct:
Proof.
intros; red; intros.
inversion WT; subst.
- simpl in TR. monadInv TR; clear TR.
+ monadInv TR.
exploit H0; eauto. intro EXEC.
destruct out; simpl; simpl in EXEC.
(* out = Out_break *)
change Out_normal with (outcome_block (Out_exit 0)).
- eapply transl_lblstmts_exit with (body := Sblock (Sseq body s0)); eauto.
+ eapply transl_lblstmts_exit with (body := Sblock (Sseq body x)); eauto.
rewrite plus_0_r.
change (Out_exit (lblstmts_length ls))
with (outcome_block (Out_exit (S (lblstmts_length ls)))).
constructor. eapply exec_Sseq_continue; eauto.
(* out = Out_continue *)
change (Out_exit ncnt) with (outcome_block (Out_exit (S ncnt))).
- eapply transl_lblstmts_exit with (body := Sblock (Sseq body s0)); eauto.
+ eapply transl_lblstmts_exit with (body := Sblock (Sseq body x)); eauto.
replace (Out_exit (lblstmts_length ls + S ncnt))
with (outcome_block (Out_exit (S (S (lblstmts_length ls + ncnt))))).
constructor. eapply exec_Sseq_continue; eauto.
@@ -1331,7 +1314,7 @@ Proof.
(* out = Out_normal *)
congruence.
(* out = Out_return *)
- eapply transl_lblstmts_return with (body := Sblock (Sseq body s0)); eauto.
+ eapply transl_lblstmts_return with (body := Sblock (Sseq body x)); eauto.
change (Out_return o)
with (outcome_block (Out_return o)).
constructor. eapply exec_Sseq_continue; eauto.
@@ -1366,13 +1349,13 @@ Proof.
inversion WT; clear WT; subst.
inversion H6; clear H6; subst.
(* Exploitation of translation hypothesis *)
- monadInv TR. subst tf. clear TR.
- monadInv EQ. clear EQ. subst f0.
+ monadInv TR.
+ monadInv EQ.
(* Allocation of variables *)
exploit match_env_alloc_variables; eauto.
apply match_globalenv_match_env_empty.
apply match_global_typenv.
- eexact (transl_fn_variables _ _ (signature_of_function f) _ _ s EQ0 EQ1).
+ eexact (transl_fn_variables _ _ (signature_of_function f) _ _ x2 EQ0 EQ).
intros [te [ALLOCVARS MATCHENV]].
(* Execution *)
econstructor; simpl.
@@ -1395,7 +1378,7 @@ Lemma transl_funcall_external_correct:
eval_funcall_prop m (External id targs tres) vargs t m vres).
Proof.
intros; red; intros.
- monadInv TR. subst tf. constructor. auto.
+ monadInv TR. constructor. auto.
Qed.
Theorem transl_funcall_correct:
@@ -1467,7 +1450,7 @@ End CORRECTNESS.
Theorem transl_program_correct:
forall prog tprog t r,
- transl_program prog = Some tprog ->
+ transl_program prog = OK tprog ->
Ctyping.wt_program prog ->
Csem.exec_program prog t r ->
Csharpminor.exec_program tprog t r.
diff --git a/cfrontend/Csyntax.v b/cfrontend/Csyntax.v
index f9463e6..6a5fcf3 100644
--- a/cfrontend/Csyntax.v
+++ b/cfrontend/Csyntax.v
@@ -1,6 +1,7 @@
(** * Abstract syntax for the Clight language *)
Require Import Coqlib.
+Require Import Errors.
Require Import Integers.
Require Import Floats.
Require Import AST.
@@ -251,17 +252,19 @@ Qed.
(** Byte offset for a field in a struct. *)
+Open Local Scope string_scope.
+
Fixpoint field_offset_rec (id: ident) (fld: fieldlist) (pos: Z)
- {struct fld} : option Z :=
+ {struct fld} : res Z :=
match fld with
- | Fnil => None
+ | Fnil => Error (MSG "Unknown field " :: CTX id :: nil)
| Fcons id' t fld' =>
if ident_eq id id'
- then Some (align pos (alignof t))
+ then OK (align pos (alignof t))
else field_offset_rec id fld' (align pos (alignof t) + sizeof t)
end.
-Definition field_offset (id: ident) (fld: fieldlist) : option Z :=
+Definition field_offset (id: ident) (fld: fieldlist) : res Z :=
field_offset_rec id fld 0.
(* Describe how a variable of the given type must be accessed:
diff --git a/common/AST.v b/common/AST.v
index 5b8c997..403861d 100644
--- a/common/AST.v
+++ b/common/AST.v
@@ -2,11 +2,14 @@
the abstract syntax trees of many of the intermediate languages. *)
Require Import Coqlib.
+Require Import Errors.
Require Import Integers.
Require Import Floats.
Set Implicit Arguments.
+(** * Syntactic elements *)
+
(** Identifiers (names of local variables, of global symbols and functions,
etc) are represented by the type [positive] of positive integers. *)
@@ -14,8 +17,9 @@ Definition ident := positive.
Definition ident_eq := peq.
-(** The languages are weakly typed, using only two types: [Tint] for
- integers and pointers, and [Tfloat] for floating-point numbers. *)
+(** The intermediate languages are weakly typed, using only two types:
+ [Tint] for integers and pointers, and [Tfloat] for floating-point
+ numbers. *)
Inductive typ : Set :=
| Tint : typ
@@ -24,6 +28,9 @@ Inductive typ : Set :=
Definition typesize (ty: typ) : Z :=
match ty with Tint => 4 | Tfloat => 8 end.
+Lemma typesize_pos: forall ty, typesize ty > 0.
+Proof. destruct ty; simpl; omega. Qed.
+
(** Additionally, function definitions and function calls are annotated
by function signatures indicating the number and types of arguments,
as well as the type of the returned value if any. These signatures
@@ -82,6 +89,14 @@ Record program (F V: Set) : Set := mkprogram {
prog_vars: list (ident * list init_data * V)
}.
+Definition prog_funct_names (F V: Set) (p: program F V) : list ident :=
+ map (@fst ident F) p.(prog_funct).
+
+Definition prog_var_names (F V: Set) (p: program F V) : list ident :=
+ map (fun x: ident * list init_data * V => fst(fst x)) p.(prog_vars).
+
+(** * Generic transformations over programs *)
+
(** We now define a general iterator over programs that applies a given
code transformation function to all function descriptions and leaves
the other parts of the program unchanged. *)
@@ -117,48 +132,63 @@ End TRANSF_PROGRAM.
code transformation function can fail and therefore returns an
option type. *)
+Open Local Scope error_monad_scope.
+Open Local Scope string_scope.
+
Section MAP_PARTIAL.
Variable A B C: Set.
-Variable f: B -> option C.
+Variable prefix_errmsg: A -> errmsg.
+Variable f: B -> res C.
-Fixpoint map_partial (l: list (A * B)) : option (list (A * C)) :=
+Fixpoint map_partial (l: list (A * B)) : res (list (A * C)) :=
match l with
- | nil => Some nil
+ | nil => OK nil
| (a, b) :: rem =>
match f b with
- | None => None
- | Some c =>
- match map_partial rem with
- | None => None
- | Some res => Some ((a, c) :: res)
- end
+ | Error msg => Error (prefix_errmsg a ++ msg)%list
+ | OK c =>
+ do rem' <- map_partial rem;
+ OK ((a, c) :: rem')
end
end.
Remark In_map_partial:
forall l l' a c,
- map_partial l = Some l' ->
+ map_partial l = OK l' ->
In (a, c) l' ->
- exists b, In (a, b) l /\ f b = Some c.
+ exists b, In (a, b) l /\ f b = OK c.
Proof.
induction l; simpl.
- intros. inversion H; subst. elim H0.
- destruct a as [a1 b1]. intros until c.
+ intros. inv H. elim H0.
+ intros until c. destruct a as [a1 b1].
caseEq (f b1); try congruence.
- intros c1 EQ1. caseEq (map_partial l); try congruence.
- intros res EQ2 EQ3 IN. inversion EQ3; clear EQ3; subst l'.
- elim IN; intro. inversion H; subst.
- exists b1; auto.
+ intro c1; intros. monadInv H0.
+ elim H1; intro. inv H0. exists b1; auto.
exploit IHl; eauto. intros [b [P Q]]. exists b; auto.
Qed.
+Remark map_partial_forall2:
+ forall l l',
+ map_partial l = OK l' ->
+ list_forall2
+ (fun (a_b: A * B) (a_c: A * C) =>
+ fst a_b = fst a_c /\ f (snd a_b) = OK (snd a_c))
+ l l'.
+Proof.
+ induction l; simpl.
+ intros. inv H. constructor.
+ intro l'. destruct a as [a b].
+ caseEq (f b). 2: congruence. intro c; intros. monadInv H0.
+ constructor. simpl. auto. auto.
+Qed.
+
End MAP_PARTIAL.
Remark map_partial_total:
- forall (A B C: Set) (f: B -> C) (l: list (A * B)),
- map_partial (fun b => Some (f b)) l =
- Some (List.map (fun a_b => (fst a_b, f (snd a_b))) l).
+ forall (A B C: Set) (prefix: A -> errmsg) (f: B -> C) (l: list (A * B)),
+ map_partial prefix (fun b => OK (f b)) l =
+ OK (List.map (fun a_b => (fst a_b, f (snd a_b))) l).
Proof.
induction l; simpl.
auto.
@@ -166,8 +196,8 @@ Proof.
Qed.
Remark map_partial_identity:
- forall (A B: Set) (l: list (A * B)),
- map_partial (fun b => Some b) l = Some l.
+ forall (A B: Set) (prefix: A -> errmsg) (l: list (A * B)),
+ map_partial prefix (fun b => OK b) l = OK l.
Proof.
induction l; simpl.
auto.
@@ -177,39 +207,39 @@ Qed.
Section TRANSF_PARTIAL_PROGRAM.
Variable A B V: Set.
-Variable transf_partial: A -> option B.
+Variable transf_partial: A -> res B.
-Function transform_partial_program (p: program A V) : option (program B V) :=
- match map_partial transf_partial p.(prog_funct) with
- | None => None
- | Some fl => Some (mkprogram fl p.(prog_main) p.(prog_vars))
- end.
+Definition prefix_funct_name (id: ident) : errmsg :=
+ MSG "In function " :: CTX id :: MSG ":\n" :: nil.
+
+Definition transform_partial_program (p: program A V) : res (program B V) :=
+ do fl <- map_partial prefix_funct_name transf_partial p.(prog_funct);
+ OK (mkprogram fl p.(prog_main) p.(prog_vars)).
Lemma transform_partial_program_function:
forall p tp i tf,
- transform_partial_program p = Some tp ->
+ transform_partial_program p = OK tp ->
In (i, tf) tp.(prog_funct) ->
- exists f, In (i, f) p.(prog_funct) /\ transf_partial f = Some tf.
+ exists f, In (i, f) p.(prog_funct) /\ transf_partial f = OK tf.
Proof.
- intros. functional inversion H.
- apply In_map_partial with fl; auto.
- inversion H; subst tp; assumption.
+ intros. monadInv H. simpl in H0.
+ eapply In_map_partial; eauto.
Qed.
Lemma transform_partial_program_main:
forall p tp,
- transform_partial_program p = Some tp ->
+ transform_partial_program p = OK tp ->
tp.(prog_main) = p.(prog_main).
Proof.
- intros. functional inversion H. reflexivity.
+ intros. monadInv H. reflexivity.
Qed.
Lemma transform_partial_program_vars:
forall p tp,
- transform_partial_program p = Some tp ->
+ transform_partial_program p = OK tp ->
tp.(prog_vars) = p.(prog_vars).
Proof.
- intros. functional inversion H. reflexivity.
+ intros. monadInv H. reflexivity.
Qed.
End TRANSF_PARTIAL_PROGRAM.
@@ -221,49 +251,104 @@ End TRANSF_PARTIAL_PROGRAM.
Section TRANSF_PARTIAL_PROGRAM2.
Variable A B V W: Set.
-Variable transf_partial_function: A -> option B.
-Variable transf_partial_variable: V -> option W.
-
-Function transform_partial_program2 (p: program A V) : option (program B W) :=
- match map_partial transf_partial_function p.(prog_funct) with
- | None => None
- | Some fl =>
- match map_partial transf_partial_variable p.(prog_vars) with
- | None => None
- | Some vl => Some (mkprogram fl p.(prog_main) vl)
- end
- end.
+Variable transf_partial_function: A -> res B.
+Variable transf_partial_variable: V -> res W.
+
+Definition prefix_var_name (id_init: ident * list init_data) : errmsg :=
+ MSG "In global variable " :: CTX (fst id_init) :: MSG ":\n" :: nil.
+
+Definition transform_partial_program2 (p: program A V) : res (program B W) :=
+ do fl <- map_partial prefix_funct_name transf_partial_function p.(prog_funct);
+ do vl <- map_partial prefix_var_name transf_partial_variable p.(prog_vars);
+ OK (mkprogram fl p.(prog_main) vl).
Lemma transform_partial_program2_function:
forall p tp i tf,
- transform_partial_program2 p = Some tp ->
+ transform_partial_program2 p = OK tp ->
In (i, tf) tp.(prog_funct) ->
- exists f, In (i, f) p.(prog_funct) /\ transf_partial_function f = Some tf.
+ exists f, In (i, f) p.(prog_funct) /\ transf_partial_function f = OK tf.
Proof.
- intros. functional inversion H.
- apply In_map_partial with fl. auto. subst tp; assumption.
+ intros. monadInv H.
+ eapply In_map_partial; eauto.
Qed.
Lemma transform_partial_program2_variable:
forall p tp i tv,
- transform_partial_program2 p = Some tp ->
+ transform_partial_program2 p = OK tp ->
In (i, tv) tp.(prog_vars) ->
- exists v, In (i, v) p.(prog_vars) /\ transf_partial_variable v = Some tv.
+ exists v, In (i, v) p.(prog_vars) /\ transf_partial_variable v = OK tv.
Proof.
- intros. functional inversion H.
- apply In_map_partial with vl. auto. subst tp; assumption.
+ intros. monadInv H.
+ eapply In_map_partial; eauto.
Qed.
Lemma transform_partial_program2_main:
forall p tp,
- transform_partial_program2 p = Some tp ->
+ transform_partial_program2 p = OK tp ->
tp.(prog_main) = p.(prog_main).
Proof.
- intros. functional inversion H. reflexivity.
+ intros. monadInv H. reflexivity.
Qed.
End TRANSF_PARTIAL_PROGRAM2.
+(** The following is a relational presentation of
+ [transform_program_partial2]. Given relations between function
+ definitions and between variable information, it defines a relation
+ between programs stating that the two programs have the same shape
+ (same global names, etc) and that identically-named function definitions
+ are variable information are related. *)
+
+Section MATCH_PROGRAM.
+
+Variable A B V W: Set.
+Variable match_fundef: A -> B -> Prop.
+Variable match_varinfo: V -> W -> Prop.
+
+Definition match_funct_entry (x1: ident * A) (x2: ident * B) :=
+ match x1, x2 with
+ | (id1, fn1), (id2, fn2) => id1 = id2 /\ match_fundef fn1 fn2
+ end.
+
+Definition match_var_entry (x1: ident * list init_data * V) (x2: ident * list init_data * W) :=
+ match x1, x2 with
+ | (id1, init1, info1), (id2, init2, info2) => id1 = id2 /\ init1 = init2 /\ match_varinfo info1 info2
+ end.
+
+Definition match_program (p1: program A V) (p2: program B W) : Prop :=
+ list_forall2 match_funct_entry p1.(prog_funct) p2.(prog_funct)
+ /\ p1.(prog_main) = p2.(prog_main)
+ /\ list_forall2 match_var_entry p1.(prog_vars) p2.(prog_vars).
+
+End MATCH_PROGRAM.
+
+Remark transform_partial_program2_match:
+ forall (A B V W: Set)
+ (transf_partial_function: A -> res B)
+ (transf_partial_variable: V -> res W)
+ (p: program A V) (tp: program B W),
+ transform_partial_program2 transf_partial_function transf_partial_variable p = OK tp ->
+ match_program
+ (fun fd tfd => transf_partial_function fd = OK tfd)
+ (fun info tinfo => transf_partial_variable info = OK tinfo)
+ p tp.
+Proof.
+ intros. monadInv H. split.
+ apply list_forall2_imply with
+ (fun (ab: ident * A) (ac: ident * B) =>
+ fst ab = fst ac /\ transf_partial_function (snd ab) = OK (snd ac)).
+ eapply map_partial_forall2. eauto.
+ intros. destruct v1; destruct v2; simpl in *. auto.
+ split. auto.
+ apply list_forall2_imply with
+ (fun (ab: ident * list init_data * V) (ac: ident * list init_data * W) =>
+ fst ab = fst ac /\ transf_partial_variable (snd ab) = OK (snd ac)).
+ eapply map_partial_forall2. eauto.
+ intros. destruct v1; destruct v2; simpl in *. destruct p0; destruct p1. intuition congruence.
+Qed.
+
+(** * External functions *)
+
(** For most languages, the functions composing the program are either
internal functions, defined within the language, or external functions
(a.k.a. system calls) that emit an event when applied. We define
@@ -296,16 +381,12 @@ End TRANSF_FUNDEF.
Section TRANSF_PARTIAL_FUNDEF.
Variable A B: Set.
-Variable transf_partial: A -> option B.
+Variable transf_partial: A -> res B.
-Definition transf_partial_fundef (fd: fundef A): option (fundef B) :=
+Definition transf_partial_fundef (fd: fundef A): res (fundef B) :=
match fd with
- | Internal f =>
- match transf_partial f with
- | None => None
- | Some f' => Some (Internal f')
- end
- | External ef => Some (External ef)
+ | Internal f => do f' <- transf_partial f; OK (Internal f')
+ | External ef => OK (External ef)
end.
End TRANSF_PARTIAL_FUNDEF.
diff --git a/common/Errors.v b/common/Errors.v
new file mode 100644
index 0000000..2c1d752
--- /dev/null
+++ b/common/Errors.v
@@ -0,0 +1,167 @@
+(** Error reporting and the error monad. *)
+
+Require Import String.
+Require Import Coqlib.
+
+Close Scope string_scope.
+
+Set Implicit Arguments.
+
+(** * Representation of error messages. *)
+
+(** Compile-time errors produce an error message, represented in Coq
+ as a list of either substrings or positive numbers encoding
+ a source-level identifier (see module AST). *)
+
+Inductive errcode: Set :=
+ | MSG: string -> errcode
+ | CTX: positive -> errcode.
+
+Definition errmsg: Set := list errcode.
+
+Definition msg (s: string) : errmsg := MSG s :: nil.
+
+(** * The error monad *)
+
+(** Compilation functions that can fail have return type [res A].
+ The return value is either [OK res] to indicate success,
+ or [Error msg] to indicate failure. *)
+
+Inductive res (A: Set) : Set :=
+| OK: A -> res A
+| Error: errmsg -> res A.
+
+Implicit Arguments Error [A].
+
+(** To automate the propagation of errors, we use a monadic style
+ with the following [bind] operation. *)
+
+Definition bind (A B: Set) (f: res A) (g: A -> res B) : res B :=
+ match f with
+ | OK x => g x
+ | Error msg => Error msg
+ end.
+
+Definition bind2 (A B C: Set) (f: res (A * B)) (g: A -> B -> res C) : res C :=
+ match f with
+ | OK (x, y) => g x y
+ | Error msg => Error msg
+ end.
+
+(** The [do] notation, inspired by Haskell's, keeps the code readable. *)
+
+Notation "'do' X <- A ; B" := (bind A (fun X => B))
+ (at level 200, X ident, A at level 100, B at level 200)
+ : error_monad_scope.
+
+Notation "'do' ( X , Y ) <- A ; B" := (bind2 A (fun X Y => B))
+ (at level 200, X ident, Y ident, A at level 100, B at level 200)
+ : error_monad_scope.
+
+Remark bind_inversion:
+ forall (A B: Set) (f: res A) (g: A -> res B) (y: B),
+ bind f g = OK y ->
+ exists x, f = OK x /\ g x = OK y.
+Proof.
+ intros until y. destruct f; simpl; intros.
+ exists a; auto.
+ discriminate.
+Qed.
+
+Remark bind2_inversion:
+ forall (A B C: Set) (f: res (A*B)) (g: A -> B -> res C) (z: C),
+ bind2 f g = OK z ->
+ exists x, exists y, f = OK (x, y) /\ g x y = OK z.
+Proof.
+ intros until z. destruct f; simpl.
+ destruct p; simpl; intros. exists a; exists b; auto.
+ intros; discriminate.
+Qed.
+
+Open Local Scope error_monad_scope.
+
+(** This is the familiar monadic map iterator. *)
+
+Fixpoint mmap (A B: Set) (f: A -> res B) (l: list A) {struct l} : res (list B) :=
+ match l with
+ | nil => OK nil
+ | hd :: tl => do hd' <- f hd; do tl' <- mmap f tl; OK (hd' :: tl')
+ end.
+
+Remark mmap_inversion:
+ forall (A B: Set) (f: A -> res B) (l: list A) (l': list B),
+ mmap f l = OK l' ->
+ list_forall2 (fun x y => f x = OK y) l l'.
+Proof.
+ induction l; simpl; intros.
+ inversion_clear H. constructor.
+ destruct (bind_inversion _ _ H) as [hd' [P Q]].
+ destruct (bind_inversion _ _ Q) as [tl' [R S]].
+ inversion_clear S.
+ constructor. auto. auto.
+Qed.
+
+(** * Reasoning over monadic computations *)
+
+(** The [monadInv H] tactic below simplifies hypotheses of the form
+<<
+ H: (do x <- a; b) = OK res
+>>
+ By definition of the bind operation, both computations [a] and
+ [b] must succeed for their composition to succeed. The tactic
+ therefore generates the following hypotheses:
+
+ x: ...
+ H1: a = OK x
+ H2: b x = OK res
+*)
+
+Ltac monadInv1 H :=
+ match type of H with
+ | (OK _ = OK _) =>
+ inversion H; clear H; try subst
+ | (Error _ = OK _) =>
+ discriminate
+ | (bind ?F ?G = OK ?X) =>
+ let x := fresh "x" in (
+ let EQ1 := fresh "EQ" in (
+ let EQ2 := fresh "EQ" in (
+ destruct (bind_inversion F G H) as [x [EQ1 EQ2]];
+ clear H;
+ try (monadInv1 EQ2))))
+ | (bind2 ?F ?G = OK ?X) =>
+ let x1 := fresh "x" in (
+ let x2 := fresh "x" in (
+ let EQ1 := fresh "EQ" in (
+ let EQ2 := fresh "EQ" in (
+ destruct (bind2_inversion F G H) as [x1 [x2 [EQ1 EQ2]]];
+ clear H;
+ try (monadInv1 EQ2)))))
+ | (mmap ?F ?L = OK ?M) =>
+ generalize (mmap_inversion F L H); intro
+ end.
+
+Ltac monadInv H :=
+ match type of H with
+ | (OK _ = OK _) => monadInv1 H
+ | (Error _ = OK _) => monadInv1 H
+ | (bind ?F ?G = OK ?X) => monadInv1 H
+ | (bind2 ?F ?G = OK ?X) => monadInv1 H
+ | (?F _ _ _ _ _ _ _ _ = OK _) =>
+ ((progress simpl in H) || unfold F in H); monadInv1 H
+ | (?F _ _ _ _ _ _ _ = OK _) =>
+ ((progress simpl in H) || unfold F in H); monadInv1 H
+ | (?F _ _ _ _ _ _ = OK _) =>
+ ((progress simpl in H) || unfold F in H); monadInv1 H
+ | (?F _ _ _ _ _ = OK _) =>
+ ((progress simpl in H) || unfold F in H); monadInv1 H
+ | (?F _ _ _ _ = OK _) =>
+ ((progress simpl in H) || unfold F in H); monadInv1 H
+ | (?F _ _ _ = OK _) =>
+ ((progress simpl in H) || unfold F in H); monadInv1 H
+ | (?F _ _ = OK _) =>
+ ((progress simpl in H) || unfold F in H); monadInv1 H
+ | (?F _ = OK _) =>
+ ((progress simpl in H) || unfold F in H); monadInv1 H
+ end.
+
diff --git a/common/Events.v b/common/Events.v
index a0559fd..e1a4729 100644
--- a/common/Events.v
+++ b/common/Events.v
@@ -1,4 +1,4 @@
-(** Representation of (traces of) observable events. *)
+(** Representation of observable events and execution traces. *)
Require Import Coqlib.
Require Import AST.
@@ -6,23 +6,77 @@ Require Import Integers.
Require Import Floats.
Require Import Values.
+(** The observable behaviour of programs is stated in terms of
+ input/output events, which can also be thought of as system calls
+ to the operating system. An event is generated each time an
+ external function (see module AST) is invoked. The event records
+ the name of the external function, the arguments to the function
+ invocation provided by the program, and the return value provided by
+ the outside world (e.g. the operating system). Arguments and values
+ are either integers or floating-point numbers. We currently do not
+ allow pointers to be exchanged between the program and the outside
+ world. *)
+
Inductive eventval: Set :=
| EVint: int -> eventval
| EVfloat: float -> eventval.
-Parameter trace: Set.
-Parameter E0: trace.
-Parameter Eextcall: ident -> list eventval -> eventval -> trace.
-Parameter Eapp: trace -> trace -> trace.
+Record event : Set := mkevent {
+ ev_name: ident;
+ ev_args: list eventval;
+ ev_res: eventval
+}.
+
+(** The dynamic semantics for programs collect traces of events.
+ Traces are of two kinds: finite (type [trace])
+ or infinite (type [traceinf]). *)
+
+Definition trace := list event.
+
+Definition E0 : trace := nil.
+
+Definition Eextcall
+ (name: ident) (args: list eventval) (res: eventval) : trace :=
+ mkevent name args res :: nil.
+
+Definition Eapp (t1 t2: trace) : trace := t1 ++ t2.
+
+CoInductive traceinf : Set :=
+ | Econsinf: event -> traceinf -> traceinf.
+
+Fixpoint Eappinf (t: trace) (T: traceinf) {struct t} : traceinf :=
+ match t with
+ | nil => T
+ | ev :: t' => Econsinf ev (Eappinf t' T)
+ end.
+
+(** Concatenation of traces is written [**] in the finite case
+ or [***] in the infinite case. *)
Infix "**" := Eapp (at level 60, right associativity).
+Infix "***" := Eappinf (at level 60, right associativity).
-Axiom E0_left: forall t, E0 ** t = t.
-Axiom E0_right: forall t, t ** E0 = t.
-Axiom Eapp_assoc: forall t1 t2 t3, (t1 ** t2) ** t3 = t1 ** (t2 ** t3).
+Lemma E0_left: forall t, E0 ** t = t.
+Proof. auto. Qed.
+
+Lemma E0_right: forall t, t ** E0 = t.
+Proof. intros. unfold E0, Eapp. rewrite <- app_nil_end. auto. Qed.
+
+Lemma Eapp_assoc: forall t1 t2 t3, (t1 ** t2) ** t3 = t1 ** (t2 ** t3).
+Proof. intros. unfold Eapp, trace. apply app_ass. Qed.
+
+Lemma Eappinf_assoc: forall t1 t2 T, (t1 ** t2) *** T = t1 *** (t2 *** T).
+Proof.
+ induction t1; intros; simpl. auto. decEq; auto.
+Qed.
Hint Rewrite E0_left E0_right Eapp_assoc: trace_rewrite.
+Opaque trace E0 Eextcall Eapp.
+
+(** The following [traceEq] tactic proves equalities between traces
+ or infinite traces. *)
+
Ltac substTraceHyp :=
match goal with
| [ H: (@eq trace ?x ?y) |- _ ] =>
@@ -40,6 +94,11 @@ Ltac decomposeTraceEq :=
Ltac traceEq :=
repeat substTraceHyp; autorewrite with trace_rewrite; decomposeTraceEq.
+(** The predicate [event_match ef vargs t vres] expresses that
+ the event [t] is generated when invoking external function [ef]
+ with arguments [vargs], and obtaining [vres] as a return value
+ from the operating system. *)
+
Inductive eventval_match: eventval -> typ -> val -> Prop :=
| ev_match_int:
forall i, eventval_match (EVint i) Tint (Vint i)
@@ -63,6 +122,10 @@ Inductive event_match:
eventval_match eres (proj_sig_res ef.(ef_sig)) vres ->
event_match ef vargs (Eextcall ef.(ef_id) eargs eres) vres.
+(** The following section shows that [event_match] is stable under
+ relocation of pointer values, as performed by memory injections
+ (see module [Mem]). *)
+
Require Import Mem.
Section EVENT_MATCH_INJECT.
@@ -101,3 +164,41 @@ Proof.
Qed.
End EVENT_MATCH_INJECT.
+
+(** The following section shows that [event_match] is stable under
+ replacement of [Vundef] values by more defined values. *)
+
+Section EVENT_MATCH_LESSDEF.
+
+Remark eventval_match_lessdef:
+ forall ev ty v1, eventval_match ev ty v1 ->
+ forall v2, Val.lessdef v1 v2 ->
+ eventval_match ev ty v2.
+Proof.
+ induction 1; intros; inv H; constructor.
+Qed.
+
+Remark eventval_list_match_moredef:
+ forall evl tyl vl1, eventval_list_match evl tyl vl1 ->
+ forall vl2, Val.lessdef_list vl1 vl2 ->
+ eventval_list_match evl tyl vl2.
+Proof.
+ induction 1; intros.
+ inversion H; constructor.
+ inversion H1; constructor.
+ eapply eventval_match_lessdef; eauto.
+ eauto.
+Qed.
+
+Lemma event_match_lessdef:
+ forall ef args1 t res1 args2,
+ event_match ef args1 t res1 ->
+ Val.lessdef_list args1 args2 ->
+ exists res2, event_match ef args2 t res2 /\ Val.lessdef res1 res2.
+Proof.
+ intros. inversion H; subst. exists res1; split.
+ constructor. eapply eventval_list_match_moredef; eauto. auto.
+ auto.
+Qed.
+
+End EVENT_MATCH_LESSDEF.
diff --git a/common/Globalenvs.v b/common/Globalenvs.v
index ccb7b03..623200f 100644
--- a/common/Globalenvs.v
+++ b/common/Globalenvs.v
@@ -19,6 +19,7 @@
system. *)
Require Import Coqlib.
+Require Import Errors.
Require Import Maps.
Require Import AST.
Require Import Integers.
@@ -60,6 +61,34 @@ Module Type GENV.
Hypothesis find_funct_find_funct_ptr:
forall (F: Set) (ge: t F) (b: block),
find_funct ge (Vptr b Int.zero) = find_funct_ptr ge b.
+
+ Hypothesis find_symbol_exists:
+ forall (F V: Set) (p: program F V)
+ (id: ident) (init: list init_data) (v: V),
+ In (id, init, v) (prog_vars p) ->
+ exists b, find_symbol (globalenv p) id = Some b.
+ Hypothesis find_funct_ptr_exists:
+ forall (F V: Set) (p: program F V) (id: ident) (f: F),
+ list_norepet (prog_funct_names p) ->
+ list_disjoint (prog_funct_names p) (prog_var_names p) ->
+ In (id, f) (prog_funct p) ->
+ exists b, find_symbol (globalenv p) id = Some b
+ /\ find_funct_ptr (globalenv p) b = Some f.
+
+ Hypothesis find_funct_ptr_inversion:
+ forall (F V: Set) (P: F -> Prop) (p: program F V) (b: block) (f: F),
+ find_funct_ptr (globalenv p) b = Some f ->
+ exists id, In (id, f) (prog_funct p).
+ Hypothesis find_funct_inversion:
+ forall (F V: Set) (P: F -> Prop) (p: program F V) (v: val) (f: F),
+ find_funct (globalenv p) v = Some f ->
+ exists id, In (id, f) (prog_funct p).
+ Hypothesis find_funct_ptr_symbol_inversion:
+ forall (F V: Set) (p: program F V) (id: ident) (b: block) (f: F),
+ find_symbol (globalenv p) id = Some b ->
+ find_funct_ptr (globalenv p) b = Some f ->
+ In (id, f) p.(prog_funct).
+
Hypothesis find_funct_ptr_prop:
forall (F V: Set) (P: F -> Prop) (p: program F V) (b: block) (f: F),
(forall id f, In (id, f) (prog_funct p) -> P f) ->
@@ -70,24 +99,19 @@ Module Type GENV.
(forall id f, In (id, f) (prog_funct p) -> P f) ->
find_funct (globalenv p) v = Some f ->
P f.
- Hypothesis find_funct_ptr_symbol_inversion:
- forall (F V: Set) (p: program F V) (id: ident) (b: block) (f: F),
- find_symbol (globalenv p) id = Some b ->
- find_funct_ptr (globalenv p) b = Some f ->
- In (id, f) p.(prog_funct).
Hypothesis initmem_nullptr:
forall (F V: Set) (p: program F V),
let m := init_mem p in
valid_block m nullptr /\
m.(blocks) nullptr = empty_block 0 0.
- Hypothesis initmem_block_init:
- forall (F V: Set) (p: program F V) (b: block),
- exists id, (init_mem p).(blocks) b = block_init_data id.
- Hypothesis find_funct_ptr_inv:
+ Hypothesis initmem_inject_neutral:
+ forall (F V: Set) (p: program F V),
+ mem_inject_neutral (init_mem p).
+ Hypothesis find_funct_ptr_negative:
forall (F V: Set) (p: program F V) (b: block) (f: F),
find_funct_ptr (globalenv p) b = Some f -> b < 0.
- Hypothesis find_symbol_inv:
+ Hypothesis find_symbol_not_fresh:
forall (F V: Set) (p: program F V) (id: ident) (b: block),
find_symbol (globalenv p) id = Some b -> b < nextblock (init_mem p).
@@ -95,74 +119,162 @@ Module Type GENV.
and operations over global environments. *)
Hypothesis find_funct_ptr_transf:
- forall (A B V: Set) (transf: A -> B) (p: program A V) (b: block) (f: A),
+ forall (A B V: Set) (transf: A -> B) (p: program A V),
+ forall (b: block) (f: A),
find_funct_ptr (globalenv p) b = Some f ->
find_funct_ptr (globalenv (transform_program transf p)) b = Some (transf f).
Hypothesis find_funct_transf:
- forall (A B V: Set) (transf: A -> B) (p: program A V) (v: val) (f: A),
+ forall (A B V: Set) (transf: A -> B) (p: program A V),
+ forall (v: val) (f: A),
find_funct (globalenv p) v = Some f ->
find_funct (globalenv (transform_program transf p)) v = Some (transf f).
Hypothesis find_symbol_transf:
- forall (A B V: Set) (transf: A -> B) (p: program A V) (s: ident),
+ forall (A B V: Set) (transf: A -> B) (p: program A V),
+ forall (s: ident),
find_symbol (globalenv (transform_program transf p)) s =
find_symbol (globalenv p) s.
Hypothesis init_mem_transf:
forall (A B V: Set) (transf: A -> B) (p: program A V),
init_mem (transform_program transf p) = init_mem p.
+ Hypothesis find_funct_ptr_rev_transf:
+ forall (A B V: Set) (transf: A -> B) (p: program A V),
+ forall (b : block) (tf : B),
+ find_funct_ptr (globalenv (transform_program transf p)) b = Some tf ->
+ exists f : A, find_funct_ptr (globalenv p) b = Some f /\ transf f = tf.
+ Hypothesis find_funct_rev_transf:
+ forall (A B V: Set) (transf: A -> B) (p: program A V),
+ forall (v : val) (tf : B),
+ find_funct (globalenv (transform_program transf p)) v = Some tf ->
+ exists f : A, find_funct (globalenv p) v = Some f /\ transf f = tf.
(** Commutation properties between partial program transformations
and operations over global environments. *)
Hypothesis find_funct_ptr_transf_partial:
- forall (A B V: Set) (transf: A -> option B)
- (p: program A V) (p': program B V),
- transform_partial_program transf p = Some p' ->
+ forall (A B V: Set) (transf: A -> res B) (p: program A V) (p': program B V),
+ transform_partial_program transf p = OK p' ->
forall (b: block) (f: A),
find_funct_ptr (globalenv p) b = Some f ->
- find_funct_ptr (globalenv p') b = transf f /\ transf f <> None.
+ exists f',
+ find_funct_ptr (globalenv p') b = Some f' /\ transf f = OK f'.
Hypothesis find_funct_transf_partial:
- forall (A B V: Set) (transf: A -> option B)
- (p: program A V) (p': program B V),
- transform_partial_program transf p = Some p' ->
+ forall (A B V: Set) (transf: A -> res B) (p: program A V) (p': program B V),
+ transform_partial_program transf p = OK p' ->
forall (v: val) (f: A),
find_funct (globalenv p) v = Some f ->
- find_funct (globalenv p') v = transf f /\ transf f <> None.
+ exists f',
+ find_funct (globalenv p') v = Some f' /\ transf f = OK f'.
Hypothesis find_symbol_transf_partial:
- forall (A B V: Set) (transf: A -> option B)
- (p: program A V) (p': program B V),
- transform_partial_program transf p = Some p' ->
+ forall (A B V: Set) (transf: A -> res B) (p: program A V) (p': program B V),
+ transform_partial_program transf p = OK p' ->
forall (s: ident),
find_symbol (globalenv p') s = find_symbol (globalenv p) s.
Hypothesis init_mem_transf_partial:
- forall (A B V: Set) (transf: A -> option B)
- (p: program A V) (p': program B V),
- transform_partial_program transf p = Some p' ->
+ forall (A B V: Set) (transf: A -> res B) (p: program A V) (p': program B V),
+ transform_partial_program transf p = OK p' ->
init_mem p' = init_mem p.
+ Hypothesis find_funct_ptr_rev_transf_partial:
+ forall (A B V: Set) (transf: A -> res B) (p: program A V) (p': program B V),
+ transform_partial_program transf p = OK p' ->
+ forall (b : block) (tf : B),
+ find_funct_ptr (globalenv p') b = Some tf ->
+ exists f : A,
+ find_funct_ptr (globalenv p) b = Some f /\ transf f = OK tf.
+ Hypothesis find_funct_rev_transf_partial:
+ forall (A B V: Set) (transf: A -> res B) (p: program A V) (p': program B V),
+ transform_partial_program transf p = OK p' ->
+ forall (v : val) (tf : B),
+ find_funct (globalenv p') v = Some tf ->
+ exists f : A,
+ find_funct (globalenv p) v = Some f /\ transf f = OK tf.
Hypothesis find_funct_ptr_transf_partial2:
- forall (A B V W: Set) (transf_fun: A -> option B) (transf_var: V -> option W)
+ forall (A B V W: Set) (transf_fun: A -> res B) (transf_var: V -> res W)
(p: program A V) (p': program B W),
- transform_partial_program2 transf_fun transf_var p = Some p' ->
+ transform_partial_program2 transf_fun transf_var p = OK p' ->
forall (b: block) (f: A),
find_funct_ptr (globalenv p) b = Some f ->
- find_funct_ptr (globalenv p') b = transf_fun f /\ transf_fun f <> None.
+ exists f',
+ find_funct_ptr (globalenv p') b = Some f' /\ transf_fun f = OK f'.
Hypothesis find_funct_transf_partial2:
- forall (A B V W: Set) (transf_fun: A -> option B) (transf_var: V -> option W)
+ forall (A B V W: Set) (transf_fun: A -> res B) (transf_var: V -> res W)
(p: program A V) (p': program B W),
- transform_partial_program2 transf_fun transf_var p = Some p' ->
+ transform_partial_program2 transf_fun transf_var p = OK p' ->
forall (v: val) (f: A),
find_funct (globalenv p) v = Some f ->
- find_funct (globalenv p') v = transf_fun f /\ transf_fun f <> None.
+ exists f',
+ find_funct (globalenv p') v = Some f' /\ transf_fun f = OK f'.
Hypothesis find_symbol_transf_partial2:
- forall (A B V W: Set) (transf_fun: A -> option B) (transf_var: V -> option W)
+ forall (A B V W: Set) (transf_fun: A -> res B) (transf_var: V -> res W)
(p: program A V) (p': program B W),
- transform_partial_program2 transf_fun transf_var p = Some p' ->
+ transform_partial_program2 transf_fun transf_var p = OK p' ->
forall (s: ident),
find_symbol (globalenv p') s = find_symbol (globalenv p) s.
Hypothesis init_mem_transf_partial2:
- forall (A B V W: Set) (transf_fun: A -> option B) (transf_var: V -> option W)
+ forall (A B V W: Set) (transf_fun: A -> res B) (transf_var: V -> res W)
+ (p: program A V) (p': program B W),
+ transform_partial_program2 transf_fun transf_var p = OK p' ->
+ init_mem p' = init_mem p.
+ Hypothesis find_funct_ptr_rev_transf_partial2:
+ forall (A B V W: Set) (transf_fun: A -> res B) (transf_var: V -> res W)
+ (p: program A V) (p': program B W),
+ transform_partial_program2 transf_fun transf_var p = OK p' ->
+ forall (b : block) (tf : B),
+ find_funct_ptr (globalenv p') b = Some tf ->
+ exists f : A,
+ find_funct_ptr (globalenv p) b = Some f /\ transf_fun f = OK tf.
+ Hypothesis find_funct_rev_transf_partial2:
+ forall (A B V W: Set) (transf_fun: A -> res B) (transf_var: V -> res W)
(p: program A V) (p': program B W),
- transform_partial_program2 transf_fun transf_var p = Some p' ->
+ transform_partial_program2 transf_fun transf_var p = OK p' ->
+ forall (v : val) (tf : B),
+ find_funct (globalenv p') v = Some tf ->
+ exists f : A,
+ find_funct (globalenv p) v = Some f /\ transf_fun f = OK tf.
+
+(** Commutation properties between matching between programs
+ and operations over global environments. *)
+
+ Hypothesis find_funct_ptr_match:
+ forall (A B V W: Set) (match_fun: A -> B -> Prop)
+ (match_var: V -> W -> Prop) (p: program A V) (p': program B W),
+ match_program match_fun match_var p p' ->
+ forall (b : block) (f : A),
+ find_funct_ptr (globalenv p) b = Some f ->
+ exists tf : B,
+ find_funct_ptr (globalenv p') b = Some tf /\ match_fun f tf.
+ Hypothesis find_funct_ptr_rev_match:
+ forall (A B V W: Set) (match_fun: A -> B -> Prop)
+ (match_var: V -> W -> Prop) (p: program A V) (p': program B W),
+ match_program match_fun match_var p p' ->
+ forall (b : block) (tf : B),
+ find_funct_ptr (globalenv p') b = Some tf ->
+ exists f : A,
+ find_funct_ptr (globalenv p) b = Some f /\ match_fun f tf.
+ Hypothesis find_funct_match:
+ forall (A B V W: Set) (match_fun: A -> B -> Prop)
+ (match_var: V -> W -> Prop) (p: program A V) (p': program B W),
+ match_program match_fun match_var p p' ->
+ forall (v : val) (f : A),
+ find_funct (globalenv p) v = Some f ->
+ exists tf : B, find_funct (globalenv p') v = Some tf /\ match_fun f tf.
+ Hypothesis find_funct_rev_match:
+ forall (A B V W: Set) (match_fun: A -> B -> Prop)
+ (match_var: V -> W -> Prop) (p: program A V) (p': program B W),
+ match_program match_fun match_var p p' ->
+ forall (v : val) (tf : B),
+ find_funct (globalenv p') v = Some tf ->
+ exists f : A, find_funct (globalenv p) v = Some f /\ match_fun f tf.
+ Hypothesis find_symbol_match:
+ forall (A B V W: Set) (match_fun: A -> B -> Prop)
+ (match_var: V -> W -> Prop) (p: program A V) (p': program B W),
+ match_program match_fun match_var p p' ->
+ forall (s : ident),
+ find_symbol (globalenv p') s = find_symbol (globalenv p) s.
+ Hypothesis init_mem_match:
+ forall (A B V W: Set) (match_fun: A -> B -> Prop)
+ (match_var: V -> W -> Prop) (p: program A V) (p': program B W),
+ match_program match_fun match_var p p' ->
init_mem p' = init_mem p.
End GENV.
@@ -280,10 +392,10 @@ Lemma initmem_nullptr:
forall (p: program F V),
let m := init_mem p in
valid_block m nullptr /\
- m.(blocks) nullptr = mkblock 0 0 (fun y => Undef) (undef_undef_outside 0 0).
+ m.(blocks) nullptr = mkblock 0 0 (fun y => Undef).
Proof.
pose (P := fun m => valid_block m nullptr /\
- m.(blocks) nullptr = mkblock 0 0 (fun y => Undef) (undef_undef_outside 0 0)).
+ m.(blocks) nullptr = mkblock 0 0 (fun y => Undef)).
assert (forall init, P (snd init) -> forall vars, P (snd (add_globals init vars))).
induction vars; simpl; intros.
auto.
@@ -297,25 +409,25 @@ Proof.
red; simpl. split. compute. auto. reflexivity.
Qed.
-Lemma initmem_block_init:
- forall (p: program F V) (b: block),
- exists id, (init_mem p).(blocks) b = block_init_data id.
+Lemma initmem_inject_neutral:
+ forall (p: program F V),
+ mem_inject_neutral (init_mem p).
Proof.
- assert (forall g0 vars g1 m b,
+ assert (forall g0 vars g1 m,
add_globals (g0, Mem.empty) vars = (g1, m) ->
- exists id, m.(blocks) b = block_init_data id).
- induction vars; simpl.
- intros. inversion H. unfold Mem.empty; simpl.
- exists (@nil init_data). symmetry. apply Mem.block_init_data_empty.
+ mem_inject_neutral m).
+ Opaque alloc_init_data.
+ induction vars; simpl.
+ intros. inv H. red; intros. destruct (load_inv _ _ _ _ _ H).
+ simpl in H1. rewrite Mem.getN_init in H1.
+ replace v with Vundef. auto. destruct chunk; simpl in H1; auto.
destruct a as [[id1 init1] info1].
- caseEq (add_globals (g0, Mem.empty) vars). intros g1 m1 EQ.
- intros g m b EQ1. injection EQ1; intros EQ2 EQ3; clear EQ1.
- rewrite <- EQ2; simpl. unfold update.
- case (zeq b (nextblock m1)); intro.
- exists init1; auto.
- eauto.
- intros. caseEq (globalenv_initmem p).
- intros g m EQ. unfold init_mem; rewrite EQ; simpl.
+ caseEq (add_globals (g0, Mem.empty) vars). intros g1 m1 EQ.
+ caseEq (alloc_init_data m1 init1). intros m2 b ALLOC.
+ intros. inv H.
+ eapply Mem.alloc_init_data_neutral; eauto.
+ intros. caseEq (globalenv_initmem p). intros g m EQ.
+ unfold init_mem; rewrite EQ; simpl.
unfold globalenv_initmem in EQ. eauto.
Qed.
@@ -325,7 +437,7 @@ Proof.
induction fns; simpl; intros. omega. unfold Zpred. omega.
Qed.
-Theorem find_funct_ptr_inv:
+Theorem find_funct_ptr_negative:
forall (p: program F V) (b: block) (f: F),
find_funct_ptr (globalenv p) b = Some f -> b < 0.
Proof.
@@ -340,7 +452,7 @@ Proof.
intros. eauto.
Qed.
-Theorem find_symbol_inv:
+Theorem find_symbol_not_fresh:
forall (p: program F V) (id: ident) (b: block),
find_symbol (globalenv p) id = Some b -> b < nextblock (init_mem p).
Proof.
@@ -358,6 +470,7 @@ Proof.
induction vars; simpl; intros until b.
intros. inversion H0. subst g m. simpl.
generalize (H fns s b H1). omega.
+ Transparent alloc_init_data.
destruct a as [[id1 init1] info1].
caseEq (add_globals (add_functs empty fns, Mem.empty) vars).
intros g1 m1 ADG EQ. inversion EQ; subst g m; clear EQ.
@@ -373,20 +486,125 @@ Qed.
End GENV.
(* Invariants on functions *)
+
+Lemma find_symbol_exists:
+ forall (F V: Set) (p: program F V)
+ (id: ident) (init: list init_data) (v: V),
+ In (id, init, v) (prog_vars p) ->
+ exists b, find_symbol (globalenv p) id = Some b.
+Proof.
+ intros until v.
+ assert (forall initm vl, In (id, init, v) vl ->
+ exists b, PTree.get id (@symbols F (fst (add_globals initm vl))) = Some b).
+ induction vl; simpl; intros.
+ elim H.
+ destruct a as [[id0 init0] v0].
+ caseEq (add_globals initm vl). intros g1 m1 EQ. simpl.
+ rewrite PTree.gsspec. destruct (peq id id0). econstructor; eauto.
+ elim H; intro. congruence. generalize (IHvl H0). rewrite EQ. auto.
+ intros. unfold globalenv, find_symbol, globalenv_initmem. auto.
+Qed.
+
+Remark find_symbol_above_nextfunction:
+ forall (F: Set) (id: ident) (b: block) (fns: list (ident * F)),
+ let g := add_functs (empty F) fns in
+ PTree.get id g.(symbols) = Some b ->
+ b > g.(nextfunction).
+Proof.
+ induction fns; simpl.
+ rewrite PTree.gempty. congruence.
+ rewrite PTree.gsspec. case (peq id (fst a)); intro.
+ intro EQ. inversion EQ. unfold Zpred. omega.
+ intros. generalize (IHfns H). unfold Zpred; omega.
+Qed.
+
+Remark find_symbol_add_globals:
+ forall (F V: Set) (id: ident) (ge_m: t F * mem) (vars: list (ident * list init_data * V)),
+ ~In id (map (fun x: ident * list init_data * V => fst(fst x)) vars) ->
+ find_symbol (fst (add_globals ge_m vars)) id =
+ find_symbol (fst ge_m) id.
+Proof.
+ unfold find_symbol; induction vars; simpl; intros.
+ auto.
+ destruct a as [[id0 init0] var0]. simpl in *.
+ caseEq (add_globals ge_m vars); intros ge' m' EQ.
+ simpl. rewrite PTree.gso. rewrite EQ in IHvars. simpl in IHvars.
+ apply IHvars. tauto. intuition congruence.
+Qed.
+
+Lemma find_funct_ptr_exists:
+ forall (F V: Set) (p: program F V) (id: ident) (f: F),
+ list_norepet (prog_funct_names p) ->
+ list_disjoint (prog_funct_names p) (prog_var_names p) ->
+ In (id, f) (prog_funct p) ->
+ exists b, find_symbol (globalenv p) id = Some b
+ /\ find_funct_ptr (globalenv p) b = Some f.
+Proof.
+ intros until f.
+ assert (forall (fns: list (ident * F)),
+ list_norepet (map (@fst ident F) fns) ->
+ In (id, f) fns ->
+ exists b, find_symbol (add_functs (empty F) fns) id = Some b
+ /\ find_funct_ptr (add_functs (empty F) fns) b = Some f).
+ unfold find_symbol, find_funct_ptr. induction fns; intros.
+ elim H0.
+ destruct a as [id0 f0]; simpl in *. inv H.
+ unfold add_funct; simpl.
+ rewrite PTree.gsspec. destruct (peq id id0).
+ subst id0. econstructor; split. eauto.
+ replace f0 with f. apply ZMap.gss.
+ elim H0; intro. congruence. elim H3.
+ change id with (@fst ident F (id, f)). apply List.in_map. auto.
+ exploit IHfns; eauto. elim H0; intro. congruence. auto.
+ intros [b [X Y]]. exists b; split. auto. rewrite ZMap.gso. auto.
+ generalize (find_symbol_above_nextfunction _ _ X).
+ unfold block; unfold ZIndexed.t; intro; omega.
+
+ intros. exploit H; eauto. assumption. intros [b [X Y]].
+ exists b; split.
+ unfold globalenv, globalenv_initmem. rewrite find_symbol_add_globals.
+ assumption. apply list_disjoint_notin with (prog_funct_names p). assumption.
+ unfold prog_funct_names. change id with (fst (id, f)).
+ apply List.in_map; auto.
+ unfold find_funct_ptr. rewrite functions_globalenv.
+ assumption.
+Qed.
+
+Lemma find_funct_ptr_inversion:
+ forall (F V: Set) (P: F -> Prop) (p: program F V) (b: block) (f: F),
+ find_funct_ptr (globalenv p) b = Some f ->
+ exists id, In (id, f) (prog_funct p).
+Proof.
+ intros until f.
+ assert (forall fns: list (ident * F),
+ find_funct_ptr (add_functs (empty F) fns) b = Some f ->
+ exists id, In (id, f) fns).
+ unfold find_funct_ptr. induction fns; simpl.
+ rewrite ZMap.gi. congruence.
+ destruct a as [id0 f0]; simpl.
+ rewrite ZMap.gsspec. destruct (ZIndexed.eq b (nextfunction (add_functs (empty F) fns))).
+ intro. inv H. exists id0; auto.
+ intro. exploit IHfns; eauto. intros [id A]. exists id; auto.
+ unfold find_funct_ptr; rewrite functions_globalenv. intros; apply H; auto.
+Qed.
+
Lemma find_funct_ptr_prop:
forall (F V: Set) (P: F -> Prop) (p: program F V) (b: block) (f: F),
(forall id f, In (id, f) (prog_funct p) -> P f) ->
find_funct_ptr (globalenv p) b = Some f ->
P f.
Proof.
- intros until f.
- unfold find_funct_ptr. rewrite functions_globalenv.
- generalize (prog_funct p). induction l; simpl.
- rewrite ZMap.gi. intros; discriminate.
- rewrite ZMap.gsspec.
- case (ZIndexed.eq b (nextfunction (add_functs (empty F) l))); intros.
- apply H with (fst a). left. destruct a. simpl in *. congruence.
- apply IHl. intros. apply H with id. right. auto. auto.
+ intros. exploit find_funct_ptr_inversion; eauto. intros [id A]. eauto.
+Qed.
+
+Lemma find_funct_inversion:
+ forall (F V: Set) (P: F -> Prop) (p: program F V) (v: val) (f: F),
+ find_funct (globalenv p) v = Some f ->
+ exists id, In (id, f) (prog_funct p).
+Proof.
+ intros. exploit find_funct_inv; eauto. intros [b EQ]. rewrite EQ in H.
+ rewrite find_funct_find_funct_ptr in H.
+ eapply find_funct_ptr_inversion; eauto.
Qed.
Lemma find_funct_prop:
@@ -395,10 +613,7 @@ Lemma find_funct_prop:
find_funct (globalenv p) v = Some f ->
P f.
Proof.
- intros until f. unfold find_funct.
- destruct v; try (intros; discriminate).
- case (Int.eq i Int.zero); [idtac | intros; discriminate].
- intros. eapply find_funct_ptr_prop; eauto.
+ intros. exploit find_funct_inversion; eauto. intros [id A]. eauto.
Qed.
Lemma find_funct_ptr_symbol_inversion:
@@ -411,15 +626,6 @@ Proof.
assert (forall fns,
let g := add_functs (empty F) fns in
PTree.get id g.(symbols) = Some b ->
- b > g.(nextfunction)).
- induction fns; simpl.
- rewrite PTree.gempty. congruence.
- rewrite PTree.gsspec. case (peq id (fst a)); intro.
- intro EQ. inversion EQ. unfold Zpred. omega.
- intros. generalize (IHfns H). unfold Zpred; omega.
- assert (forall fns,
- let g := add_functs (empty F) fns in
- PTree.get id g.(symbols) = Some b ->
ZMap.get b g.(functions) = Some f ->
In (id, f) fns).
induction fns; simpl.
@@ -430,216 +636,336 @@ Proof.
intro EQ. inversion EQ. unfold ZIndexed.eq. rewrite zeq_true.
intro EQ2. left. destruct a. simpl in *. congruence.
intro. unfold ZIndexed.eq. rewrite zeq_false. intro. eauto.
- generalize (H _ H0). fold g. unfold block. omega.
+ generalize (find_symbol_above_nextfunction _ _ H). fold g. unfold block. omega.
assert (forall g0 m0, b < 0 ->
forall vars g m,
@add_globals F V (g0, m0) vars = (g, m) ->
PTree.get id g.(symbols) = Some b ->
PTree.get id g0.(symbols) = Some b).
induction vars; simpl.
- intros. inversion H2. auto.
+ intros. inv H1. auto.
destruct a as [[id1 init1] info1]. caseEq (add_globals (g0, m0) vars).
intros g1 m1 EQ g m EQ1. injection EQ1; simpl; clear EQ1.
unfold add_symbol; intros A B. rewrite <- B. simpl.
rewrite PTree.gsspec. case (peq id id1); intros.
- assert (b > 0). injection H2; intros. rewrite <- H3. apply nextblock_pos.
+ assert (b > 0). inv H1. apply nextblock_pos.
omegaContradiction.
eauto.
intros.
- generalize (find_funct_ptr_inv _ _ H3). intro.
+ generalize (find_funct_ptr_negative _ _ H2). intro.
pose (g := add_functs (empty F) (prog_funct p)).
- apply H0.
- apply H1 with Mem.empty (prog_vars p) (globalenv p) (init_mem p).
+ apply H.
+ apply H0 with Mem.empty (prog_vars p) (globalenv p) (init_mem p).
auto. unfold globalenv, init_mem. rewrite <- surjective_pairing.
reflexivity. assumption. rewrite <- functions_globalenv. assumption.
Qed.
(* Global environments and program transformations. *)
-Section TRANSF_PROGRAM_PARTIAL2.
+Section MATCH_PROGRAM.
Variable A B V W: Set.
-Variable transf_fun: A -> option B.
-Variable transf_var: V -> option W.
+Variable match_fun: A -> B -> Prop.
+Variable match_var: V -> W -> Prop.
Variable p: program A V.
Variable p': program B W.
-Hypothesis transf_OK:
- transform_partial_program2 transf_fun transf_var p = Some p'.
+Hypothesis match_prog:
+ match_program match_fun match_var p p'.
-Lemma add_functs_transf:
+Lemma add_functs_match:
forall (fns: list (ident * A)) (tfns: list (ident * B)),
- map_partial transf_fun fns = Some tfns ->
+ list_forall2 (match_funct_entry match_fun) fns tfns ->
let r := add_functs (empty A) fns in
let tr := add_functs (empty B) tfns in
nextfunction tr = nextfunction r /\
symbols tr = symbols r /\
forall (b: block) (f: A),
ZMap.get b (functions r) = Some f ->
- ZMap.get b (functions tr) = transf_fun f /\ transf_fun f <> None.
+ exists tf, ZMap.get b (functions tr) = Some tf /\ match_fun f tf.
Proof.
- induction fns; simpl.
+ induction 1; simpl.
- intros; injection H; intro; subst tfns.
- simpl. split. reflexivity. split. reflexivity.
+ split. reflexivity. split. reflexivity.
intros b f; repeat (rewrite ZMap.gi). intros; discriminate.
- intro tfns. destruct a. caseEq (transf_fun a). intros a' TA.
- caseEq (map_partial transf_fun fns). intros l TPP EQ.
- injection EQ; intro; subst tfns.
- clear EQ. simpl.
- generalize (IHfns l TPP).
- intros [HR1 [HR2 HR3]].
- rewrite HR1. rewrite HR2.
- split. reflexivity.
- split. reflexivity.
+ destruct a1 as [id1 fn1]. destruct b1 as [id2 fn2].
+ simpl. red in H. destruct H.
+ destruct IHlist_forall2 as [X [Y Z]].
+ rewrite X. rewrite Y.
+ split. auto.
+ split. congruence.
intros b f.
- case (zeq b (nextfunction (add_functs (empty A) fns))); intro.
- subst b. repeat (rewrite ZMap.gss).
- intro EQ; injection EQ; intro; subst f; clear EQ.
- rewrite TA. split. auto. discriminate.
- repeat (rewrite ZMap.gso; auto).
+ repeat (rewrite ZMap.gsspec).
+ destruct (ZIndexed.eq b (nextfunction (add_functs (empty A) al))).
+ intro EQ; inv EQ. exists fn2; auto.
+ auto.
+Qed.
- intros; discriminate.
- intros; discriminate.
+Lemma add_functs_rev_match:
+ forall (fns: list (ident * A)) (tfns: list (ident * B)),
+ list_forall2 (match_funct_entry match_fun) fns tfns ->
+ let r := add_functs (empty A) fns in
+ let tr := add_functs (empty B) tfns in
+ nextfunction tr = nextfunction r /\
+ symbols tr = symbols r /\
+ forall (b: block) (tf: B),
+ ZMap.get b (functions tr) = Some tf ->
+ exists f, ZMap.get b (functions r) = Some f /\ match_fun f tf.
+Proof.
+ induction 1; simpl.
+
+ split. reflexivity. split. reflexivity.
+ intros b f; repeat (rewrite ZMap.gi). intros; discriminate.
+
+ destruct a1 as [id1 fn1]. destruct b1 as [id2 fn2].
+ simpl. red in H. destruct H.
+ destruct IHlist_forall2 as [X [Y Z]].
+ rewrite X. rewrite Y.
+ split. auto.
+ split. congruence.
+ intros b f.
+ repeat (rewrite ZMap.gsspec).
+ destruct (ZIndexed.eq b (nextfunction (add_functs (empty A) al))).
+ intro EQ; inv EQ. exists fn1; auto.
+ auto.
Qed.
-Lemma mem_add_globals_transf:
+Lemma mem_add_globals_match:
forall (g1: genv A) (g2: genv B) (m: mem)
(vars: list (ident * list init_data * V))
(tvars: list (ident * list init_data * W)),
- map_partial transf_var vars = Some tvars ->
+ list_forall2 (match_var_entry match_var) vars tvars ->
snd (add_globals (g1, m) vars) = snd (add_globals (g2, m) tvars).
Proof.
- induction vars; simpl.
- intros. inversion H. reflexivity.
- intro. destruct a as [[id1 init1] info1].
- caseEq (transf_var info1); try congruence.
- intros tinfo1 EQ1.
- caseEq (map_partial transf_var vars); try congruence.
- intros tvars' EQ2 EQ3.
- inversion EQ3. simpl.
- generalize (IHvars _ EQ2).
- destruct (add_globals (g1, m) vars).
- destruct (add_globals (g2, m) tvars').
+ induction 1; simpl.
+ auto.
+ destruct a1 as [[id1 init1] info1].
+ destruct b1 as [[id2 init2] info2].
+ red in H. destruct H as [X [Y Z]]. subst id2 init2.
+ generalize IHlist_forall2.
+ destruct (add_globals (g1, m) al).
+ destruct (add_globals (g2, m) bl).
simpl. intro. subst m1. auto.
Qed.
-Lemma symbols_add_globals_transf:
+Lemma symbols_add_globals_match:
forall (g1: genv A) (g2: genv B) (m: mem),
symbols g1 = symbols g2 ->
forall (vars: list (ident * list init_data * V))
(tvars: list (ident * list init_data * W)),
- map_partial transf_var vars = Some tvars ->
+ list_forall2 (match_var_entry match_var) vars tvars ->
symbols (fst (add_globals (g1, m) vars)) =
symbols (fst (add_globals (g2, m) tvars)).
Proof.
- induction vars; simpl.
- intros. inversion H0. assumption.
- intro. destruct a as [[id1 init1] info1].
- caseEq (transf_var info1); try congruence. intros tinfo1 EQ1.
- caseEq (map_partial transf_var vars); try congruence.
- intros tvars' EQ2 EQ3. inversion EQ3; simpl.
- generalize (IHvars _ EQ2).
- generalize (mem_add_globals_transf g1 g2 m vars EQ2).
- destruct (add_globals (g1, m) vars).
- destruct (add_globals (g2, m) tvars').
+ induction 2; simpl.
+ auto.
+ destruct a1 as [[id1 init1] info1].
+ destruct b1 as [[id2 init2] info2].
+ red in H0. destruct H0 as [X [Y Z]]. subst id2 init2.
+ generalize IHlist_forall2.
+ generalize (mem_add_globals_match g1 g2 m H1).
+ destruct (add_globals (g1, m) al).
+ destruct (add_globals (g2, m) bl).
simpl. intros. congruence.
Qed.
-(*
-Lemma prog_funct_transf_OK:
- transf_partial_program transf p.(prog_funct) = Some p'.(prog_funct).
+Theorem find_funct_ptr_match:
+ forall (b: block) (f: A),
+ find_funct_ptr (globalenv p) b = Some f ->
+ exists tf, find_funct_ptr (globalenv p') b = Some tf /\ match_fun f tf.
Proof.
- generalize transf_OK; unfold transform_partial_program.
- case (transf_partial_program transf (prog_funct p)); simpl; intros.
- injection transf_OK0; intros; subst p'. reflexivity.
- discriminate.
+ intros until f. destruct match_prog as [X [Y Z]].
+ destruct (add_functs_match X) as [P [Q R]].
+ unfold find_funct_ptr. repeat rewrite functions_globalenv.
+ auto.
Qed.
-*)
-Theorem find_funct_ptr_transf_partial2:
- forall (b: block) (f: A),
- find_funct_ptr (globalenv p) b = Some f ->
- find_funct_ptr (globalenv p') b = transf_fun f /\ transf_fun f <> None.
+Theorem find_funct_ptr_rev_match:
+ forall (b: block) (tf: B),
+ find_funct_ptr (globalenv p') b = Some tf ->
+ exists f, find_funct_ptr (globalenv p) b = Some f /\ match_fun f tf.
Proof.
- intros until f. functional inversion transf_OK.
- destruct (add_functs_transf _ H0) as [P [Q R]].
- unfold find_funct_ptr. repeat rewrite functions_globalenv. simpl.
+ intros until tf. destruct match_prog as [X [Y Z]].
+ destruct (add_functs_rev_match X) as [P [Q R]].
+ unfold find_funct_ptr. repeat rewrite functions_globalenv.
auto.
Qed.
-Theorem find_funct_transf_partial2:
+Theorem find_funct_match:
forall (v: val) (f: A),
find_funct (globalenv p) v = Some f ->
- find_funct (globalenv p') v = transf_fun f /\ transf_fun f <> None.
+ exists tf, find_funct (globalenv p') v = Some tf /\ match_fun f tf.
Proof.
intros until f. unfold find_funct.
case v; try (intros; discriminate).
intros b ofs.
case (Int.eq ofs Int.zero); try (intros; discriminate).
- apply find_funct_ptr_transf_partial2.
+ apply find_funct_ptr_match.
Qed.
-Lemma symbols_init_transf2:
+Theorem find_funct_rev_match:
+ forall (v: val) (tf: B),
+ find_funct (globalenv p') v = Some tf ->
+ exists f, find_funct (globalenv p) v = Some f /\ match_fun f tf.
+Proof.
+ intros until tf. unfold find_funct.
+ case v; try (intros; discriminate).
+ intros b ofs.
+ case (Int.eq ofs Int.zero); try (intros; discriminate).
+ apply find_funct_ptr_rev_match.
+Qed.
+
+Lemma symbols_init_match:
symbols (globalenv p') = symbols (globalenv p).
Proof.
unfold globalenv. unfold globalenv_initmem.
- functional inversion transf_OK.
- destruct (add_functs_transf _ H0) as [P [Q R]].
- simpl. symmetry. apply symbols_add_globals_transf. auto. auto.
+ destruct match_prog as [X [Y Z]].
+ destruct (add_functs_match X) as [P [Q R]].
+ simpl. symmetry. apply symbols_add_globals_match. auto. auto.
Qed.
-Theorem find_symbol_transf_partial2:
+Theorem find_symbol_match:
forall (s: ident),
find_symbol (globalenv p') s = find_symbol (globalenv p) s.
Proof.
intros. unfold find_symbol.
- rewrite symbols_init_transf2. auto.
+ rewrite symbols_init_match. auto.
+Qed.
+
+Theorem init_mem_match:
+ init_mem p' = init_mem p.
+Proof.
+ unfold init_mem. unfold globalenv_initmem.
+ destruct match_prog as [X [Y Z]].
+ symmetry. apply mem_add_globals_match. auto.
+Qed.
+
+End MATCH_PROGRAM.
+
+Section TRANSF_PROGRAM_PARTIAL2.
+
+Variable A B V W: Set.
+Variable transf_fun: A -> res B.
+Variable transf_var: V -> res W.
+Variable p: program A V.
+Variable p': program B W.
+Hypothesis transf_OK:
+ transform_partial_program2 transf_fun transf_var p = OK p'.
+
+Remark prog_match:
+ match_program
+ (fun fd tfd => transf_fun fd = OK tfd)
+ (fun info tinfo => transf_var info = OK tinfo)
+ p p'.
+Proof.
+ apply transform_partial_program2_match; auto.
+Qed.
+
+Theorem find_funct_ptr_transf_partial2:
+ forall (b: block) (f: A),
+ find_funct_ptr (globalenv p) b = Some f ->
+ exists f',
+ find_funct_ptr (globalenv p') b = Some f' /\ transf_fun f = OK f'.
+Proof.
+ intros.
+ exploit find_funct_ptr_match. eexact prog_match. eauto.
+ intros [tf [X Y]]. exists tf; auto.
+Qed.
+
+Theorem find_funct_ptr_rev_transf_partial2:
+ forall (b: block) (tf: B),
+ find_funct_ptr (globalenv p') b = Some tf ->
+ exists f, find_funct_ptr (globalenv p) b = Some f /\ transf_fun f = OK tf.
+Proof.
+ intros.
+ exploit find_funct_ptr_rev_match. eexact prog_match. eauto. auto.
+Qed.
+
+Theorem find_funct_transf_partial2:
+ forall (v: val) (f: A),
+ find_funct (globalenv p) v = Some f ->
+ exists f',
+ find_funct (globalenv p') v = Some f' /\ transf_fun f = OK f'.
+Proof.
+ intros.
+ exploit find_funct_match. eexact prog_match. eauto.
+ intros [tf [X Y]]. exists tf; auto.
+Qed.
+
+Theorem find_funct_rev_transf_partial2:
+ forall (v: val) (tf: B),
+ find_funct (globalenv p') v = Some tf ->
+ exists f, find_funct (globalenv p) v = Some f /\ transf_fun f = OK tf.
+Proof.
+ intros.
+ exploit find_funct_rev_match. eexact prog_match. eauto. auto.
+Qed.
+
+Theorem find_symbol_transf_partial2:
+ forall (s: ident),
+ find_symbol (globalenv p') s = find_symbol (globalenv p) s.
+Proof.
+ intros. eapply find_symbol_match. eexact prog_match.
Qed.
Theorem init_mem_transf_partial2:
init_mem p' = init_mem p.
Proof.
- unfold init_mem. unfold globalenv_initmem.
- functional inversion transf_OK.
- simpl. symmetry. apply mem_add_globals_transf. auto.
+ intros. eapply init_mem_match. eexact prog_match.
Qed.
End TRANSF_PROGRAM_PARTIAL2.
-
Section TRANSF_PROGRAM_PARTIAL.
Variable A B V: Set.
-Variable transf: A -> option B.
+Variable transf: A -> res B.
Variable p: program A V.
Variable p': program B V.
-Hypothesis transf_OK: transform_partial_program transf p = Some p'.
+Hypothesis transf_OK: transform_partial_program transf p = OK p'.
Remark transf2_OK:
- transform_partial_program2 transf (fun x => Some x) p = Some p'.
+ transform_partial_program2 transf (fun x => OK x) p = OK p'.
Proof.
rewrite <- transf_OK. unfold transform_partial_program2, transform_partial_program.
- destruct (map_partial transf (prog_funct p)); auto.
+ destruct (map_partial prefix_funct_name transf (prog_funct p)); auto.
rewrite map_partial_identity; auto.
Qed.
Theorem find_funct_ptr_transf_partial:
forall (b: block) (f: A),
find_funct_ptr (globalenv p) b = Some f ->
- find_funct_ptr (globalenv p') b = transf f /\ transf f <> None.
+ exists f',
+ find_funct_ptr (globalenv p') b = Some f' /\ transf f = OK f'.
Proof.
exact (@find_funct_ptr_transf_partial2 _ _ _ _ _ _ _ _ transf2_OK).
Qed.
+Theorem find_funct_ptr_rev_transf_partial:
+ forall (b: block) (tf: B),
+ find_funct_ptr (globalenv p') b = Some tf ->
+ exists f, find_funct_ptr (globalenv p) b = Some f /\ transf f = OK tf.
+Proof.
+ exact (@find_funct_ptr_rev_transf_partial2 _ _ _ _ _ _ _ _ transf2_OK).
+Qed.
+
Theorem find_funct_transf_partial:
forall (v: val) (f: A),
find_funct (globalenv p) v = Some f ->
- find_funct (globalenv p') v = transf f /\ transf f <> None.
+ exists f',
+ find_funct (globalenv p') v = Some f' /\ transf f = OK f'.
Proof.
exact (@find_funct_transf_partial2 _ _ _ _ _ _ _ _ transf2_OK).
Qed.
+Theorem find_funct_rev_transf_partial:
+ forall (v: val) (tf: B),
+ find_funct (globalenv p') v = Some tf ->
+ exists f, find_funct (globalenv p) v = Some f /\ transf f = OK tf.
+Proof.
+ exact (@find_funct_rev_transf_partial2 _ _ _ _ _ _ _ _ transf2_OK).
+Qed.
+
Theorem find_symbol_transf_partial:
forall (s: ident),
find_symbol (globalenv p') s = find_symbol (globalenv p) s.
@@ -663,7 +989,7 @@ Variable p: program A V.
Let tp := transform_program transf p.
Remark transf_OK:
- transform_partial_program (fun x => Some (transf x)) p = Some tp.
+ transform_partial_program (fun x => OK (transf x)) p = OK tp.
Proof.
unfold tp, transform_program, transform_partial_program.
rewrite map_partial_total. reflexivity.
@@ -676,7 +1002,16 @@ Theorem find_funct_ptr_transf:
Proof.
intros.
destruct (@find_funct_ptr_transf_partial _ _ _ _ _ _ transf_OK _ _ H)
- as [X Y]. auto.
+ as [f' [X Y]]. congruence.
+Qed.
+
+Theorem find_funct_ptr_rev_transf:
+ forall (b: block) (tf: B),
+ find_funct_ptr (globalenv tp) b = Some tf ->
+ exists f, find_funct_ptr (globalenv p) b = Some f /\ transf f = tf.
+Proof.
+ intros. exploit find_funct_ptr_rev_transf_partial. eexact transf_OK. eauto.
+ intros [f [X Y]]. exists f; split. auto. congruence.
Qed.
Theorem find_funct_transf:
@@ -686,7 +1021,16 @@ Theorem find_funct_transf:
Proof.
intros.
destruct (@find_funct_transf_partial _ _ _ _ _ _ transf_OK _ _ H)
- as [X Y]. auto.
+ as [f' [X Y]]. congruence.
+Qed.
+
+Theorem find_funct_rev_transf:
+ forall (v: val) (tf: B),
+ find_funct (globalenv tp) v = Some tf ->
+ exists f, find_funct (globalenv p) v = Some f /\ transf f = tf.
+Proof.
+ intros. exploit find_funct_rev_transf_partial. eexact transf_OK. eauto.
+ intros [f [X Y]]. exists f; split. auto. congruence.
Qed.
Theorem find_symbol_transf:
diff --git a/common/Main.v b/common/Main.v
index f472ec3..33bc783 100644
--- a/common/Main.v
+++ b/common/Main.v
@@ -1,40 +1,48 @@
-(** The compiler back-end and its proof of semantic preservation *)
+(** The whole compiler and its proof of semantic preservation *)
(** Libraries. *)
Require Import Coqlib.
Require Import Maps.
+Require Import Errors.
Require Import AST.
Require Import Values.
+Require Import Smallstep.
(** Languages (syntax and semantics). *)
Require Csyntax.
Require Csem.
Require Csharpminor.
Require Cminor.
+Require CminorSel.
Require RTL.
Require LTL.
+Require LTLin.
Require Linear.
Require Mach.
Require PPC.
(** Translation passes. *)
Require Cshmgen.
Require Cminorgen.
+Require Selection.
Require RTLgen.
Require Constprop.
Require CSE.
Require Allocation.
Require Tunneling.
Require Linearize.
+Require Reload.
Require Stacking.
Require PPCgen.
(** Type systems. *)
Require Ctyping.
Require RTLtyping.
Require LTLtyping.
+Require LTLintyping.
Require Lineartyping.
Require Machtyping.
(** Proofs of semantic preservation and typing preservation. *)
Require Cshmgenproof3.
Require Cminorgenproof.
+Require Selectionproof.
Require RTLgenproof.
Require Constpropproof.
Require CSEproof.
@@ -44,266 +52,234 @@ Require Tunnelingproof.
Require Tunnelingtyping.
Require Linearizeproof.
Require Linearizetyping.
+Require Reloadproof.
+Require Reloadtyping.
Require Stackingproof.
Require Stackingtyping.
-Require Machabstr2mach.
+Require Machabstr2concr.
Require PPCgenproof.
+Open Local Scope string_scope.
+
(** * Composing the translation passes *)
(** We first define useful monadic composition operators,
along with funny (but convenient) notations. *)
-Definition apply_total (A B: Set) (x: option A) (f: A -> B) : option B :=
- match x with None => None | Some x1 => Some (f x1) end.
+Definition apply_total (A B: Set) (x: res A) (f: A -> B) : res B :=
+ match x with Error msg => Error msg | OK x1 => OK (f x1) end.
Definition apply_partial (A B: Set)
- (x: option A) (f: A -> option B) : option B :=
- match x with None => None | Some x1 => f x1 end.
+ (x: res A) (f: A -> res B) : res B :=
+ match x with Error msg => Error msg | OK x1 => f x1 end.
Notation "a @@@ b" :=
(apply_partial _ _ a b) (at level 50, left associativity).
Notation "a @@ b" :=
(apply_total _ _ a b) (at level 50, left associativity).
-(** We define two translation functions for whole programs: one starting with
- a C program, the other with a Cminor program. Both
- translations produce PPC programs ready for pretty-printing and
- assembling.
+(** We define three translation functions for whole programs: one
+ starting with a C program, one with a Cminor program, one with an
+ RTL program. The three translations produce PPC programs ready for
+ pretty-printing and assembling.
- There are two ways to compose the compiler passes. The first translates
- every function from the Cminor program from Cminor to RTL, then to LTL, etc,
- all the way to PPC, and iterates this transformation for every function.
- The second translates the whole Cminor program to a RTL program, then to
- an LTL program, etc. We follow the first approach because it has lower
- memory requirements.
+ There are two ways to compose the compiler passes. The first
+ translates every function from the Cminor program from Cminor to
+ RTL, then to LTL, etc, all the way to PPC, and iterates this
+ transformation for every function. The second translates the whole
+ Cminor program to a RTL program, then to an LTL program, etc.
+ Between Cminor and PPC, we follow the first approach because it has
+ lower memory requirements. The translation from Clight to PPC
+ follows the second approach.
- The translation of a Cminor function to a PPC function is as follows. *)
+ The translation of an RTL function to a PPC function is as follows. *)
-Definition transf_cminor_fundef (f: Cminor.fundef) : option PPC.fundef :=
- Some f
- @@@ RTLgen.transl_fundef
+Definition transf_rtl_fundef (f: RTL.fundef) : res PPC.fundef :=
+ OK f
@@ Constprop.transf_fundef
@@ CSE.transf_fundef
@@@ Allocation.transf_fundef
@@ Tunneling.tunnel_fundef
@@ Linearize.transf_fundef
+ @@ Reload.transf_fundef
@@@ Stacking.transf_fundef
@@@ PPCgen.transf_fundef.
+(* Here is the translation of a Cminor function to a PPC function. *)
+
+Definition transf_cminor_fundef (f: Cminor.fundef) : res PPC.fundef :=
+ OK f
+ @@ Selection.sel_fundef
+ @@@ RTLgen.transl_fundef
+ @@@ transf_rtl_fundef.
+
(** The corresponding translations for whole program follow. *)
-Definition transf_cminor_program (p: Cminor.program) : option PPC.program :=
+Definition transf_rtl_program (p: RTL.program) : res PPC.program :=
+ transform_partial_program transf_rtl_fundef p.
+
+Definition transf_cminor_program (p: Cminor.program) : res PPC.program :=
transform_partial_program transf_cminor_fundef p.
-Definition transf_c_program (p: Csyntax.program) : option PPC.program :=
+Definition transf_c_program (p: Csyntax.program) : res PPC.program :=
match Ctyping.typecheck_program p with
- | false => None
+ | false =>
+ Error (msg "Ctyping: type error")
| true =>
- Some p
+ OK p
@@@ Cshmgen.transl_program
@@@ Cminorgen.transl_program
@@@ transf_cminor_program
end.
-(** * Equivalence with whole program transformations *)
-
-(** To prove semantic preservation for the whole compiler, it is easier to reason
- over the second way to compose the compiler pass: the one that translate
- whole programs through each compiler pass. We now define this second translation
- and prove that it produces the same PPC programs as the first translation. *)
-
-Definition transf_cminor_program2 (p: Cminor.program) : option PPC.program :=
- Some p
- @@@ RTLgen.transl_program
- @@ Constprop.transf_program
- @@ CSE.transf_program
- @@@ Allocation.transf_program
- @@ Tunneling.tunnel_program
- @@ Linearize.transf_program
- @@@ Stacking.transf_program
- @@@ PPCgen.transf_program.
+(** The following lemmas help reason over compositions of passes. *)
Lemma map_partial_compose:
forall (X A B C: Set)
- (f1: A -> option B) (f2: B -> option C)
- (p: list (X * A)),
- map_partial f1 p @@@ map_partial f2 =
- map_partial (fun f => f1 f @@@ f2) p.
+ (ctx: X -> errmsg)
+ (f1: A -> res B) (f2: B -> res C)
+ (pa: list (X * A)) (pc: list (X * C)),
+ map_partial ctx (fun f => f1 f @@@ f2) pa = OK pc ->
+ exists pb, map_partial ctx f1 pa = OK pb /\ map_partial ctx f2 pb = OK pc.
Proof.
- induction p. simpl. auto.
- simpl. destruct a. destruct (f1 a).
- simpl. simpl in IHp. destruct (map_partial f1 p).
- simpl. simpl in IHp. destruct (f2 b).
- destruct (map_partial f2 l).
- rewrite <- IHp. auto.
- rewrite <- IHp. auto.
- auto.
- simpl. rewrite <- IHp. simpl. destruct (f2 b); auto.
- simpl. auto.
+ induction pa; simpl.
+ intros. inv H. econstructor; eauto.
+ intro pc. destruct a as [x a].
+ caseEq (f1 a); simpl; try congruence. intros b F1.
+ caseEq (f2 b); simpl; try congruence. intros c F2 EQ.
+ monadInv EQ. exploit IHpa; eauto. intros [pb [P Q]].
+ rewrite P; simpl.
+ exists ((x, b) :: pb); split. auto. simpl. rewrite F2. rewrite Q. auto.
Qed.
-(*
-Lemma transform_partial_program2_compose:
- forall (A B C V W X: Set)
- (f1: A -> option B) (g1: V -> option W)
- (f2: B -> option C) (g2: W -> option X)
- (p: program A V),
- transform_partial_program2 f1 g1 p @@@
- (fun p' => transform_partial_program2 f2 g2 p') =
- transform_partial_program2 (fun x => f1 x @@@ f2) (fun x => g1 x @@@ g2) p.
+Lemma transform_partial_program_compose:
+ forall (A B C V: Set)
+ (f1: A -> res B) (f2: B -> res C)
+ (pa: program A V) (pc: program C V),
+ transform_partial_program (fun f => f1 f @@@ f2) pa = OK pc ->
+ exists pb, transform_partial_program f1 pa = OK pb /\
+ transform_partial_program f2 pb = OK pc.
Proof.
- unfold transform_partial_program2; intros.
- rewrite <- map_partial_compose; simpl.
- rewrite <- map_partial_compose; simpl.
- destruct (map_partial f1 (prog_funct p)); simpl; auto.
- destruct (map_partial g1 (prog_vars p)); simpl; auto.
- destruct (map_partial f2 l); auto.
+ intros. monadInv H.
+ exploit map_partial_compose; eauto. intros [xb [P Q]].
+ exists (mkprogram xb (prog_main pa) (prog_vars pa)); split.
+ unfold transform_partial_program. rewrite P; auto.
+ unfold transform_partial_program. simpl. rewrite Q; auto.
Qed.
-Lemma transform_program_partial2_partial:
- forall (A B V: Set) (f: A -> option B) (p: program A V),
- transform_partial_program f p =
- transform_partial_program2 f (fun x => Some x) p.
+Lemma transform_program_partial_program:
+ forall (A B V: Set) (f: A -> B) (p: program A V) (tp: program B V),
+ transform_partial_program (fun x => OK (f x)) p = OK tp ->
+ transform_program f p = tp.
Proof.
- intros. unfold transform_partial_program, transform_partial_program2.
- rewrite map_partial_identity. auto.
+ intros until tp. unfold transform_partial_program.
+ rewrite map_partial_total. simpl. intros. inv H. auto.
Qed.
-Lemma apply_partial_transf_program:
- forall (A B V: Set) (f: A -> option B) (x: option (program A V)),
- x @@@ (fun p => transform_partial_program f p) =
- x @@@ (fun p => transform_partial_program2 f (fun x => Some x) p).
-Proof.
- intros. unfold apply_partial.
- destruct x. apply transform_program_partial2_partial. auto.
-Qed.
-*)
-Lemma transform_partial_program_compose:
+Lemma transform_program_compose:
forall (A B C V: Set)
- (f1: A -> option B) (f2: B -> option C)
- (p: program A V),
- transform_partial_program f1 p @@@
- (fun p' => transform_partial_program f2 p') =
- transform_partial_program (fun f => f1 f @@@ f2) p.
+ (f1: A -> res B) (f2: B -> C)
+ (pa: program A V) (pc: program C V),
+ transform_partial_program (fun f => f1 f @@ f2) pa = OK pc ->
+ exists pb, transform_partial_program f1 pa = OK pb /\
+ transform_program f2 pb = pc.
Proof.
- unfold transform_partial_program; intros.
- rewrite <- map_partial_compose. simpl.
- destruct (map_partial f1 (prog_funct p)); simpl.
- auto. auto.
+ intros.
+ replace (fun f : A => f1 f @@ f2)
+ with (fun f : A => f1 f @@@ (fun x => OK (f2 x))) in H.
+ exploit transform_partial_program_compose; eauto.
+ intros [pb [X Y]]. exists pb; split. auto.
+ apply transform_program_partial_program. auto.
+ apply extensionality; intro. destruct(f1 x); auto.
Qed.
-Lemma transform_program_partial_total:
- forall (A B V: Set) (f: A -> B) (p: program A V),
- Some (transform_program f p) =
- transform_partial_program (fun x => Some (f x)) p.
+Lemma transform_partial_program_identity:
+ forall (A V: Set) (pa pb: program A V),
+ transform_partial_program (@OK A) pa = OK pb ->
+ pa = pb.
Proof.
- intros. unfold transform_program, transform_partial_program.
- rewrite map_partial_total. auto.
+ intros until pb. unfold transform_partial_program.
+ replace (@OK A) with (fun b => @OK A b).
+ rewrite map_partial_identity. simpl. destruct pa; simpl; congruence.
+ apply extensionality; auto.
Qed.
-Lemma apply_total_transf_program:
- forall (A B V: Set) (f: A -> B) (x: option (program A V)),
- x @@ (fun p => transform_program f p) =
- x @@@ (fun p => transform_partial_program (fun x => Some (f x)) p).
-Proof.
- intros. unfold apply_total, apply_partial.
- destruct x. apply transform_program_partial_total. auto.
-Qed.
+(** * Semantic preservation *)
-Lemma transf_cminor_program_equiv:
- forall p, transf_cminor_program2 p = transf_cminor_program p.
-Proof.
- intro. unfold transf_cminor_program, transf_cminor_program2, transf_cminor_fundef.
- simpl.
- unfold RTLgen.transl_program,
- Constprop.transf_program, RTL.program.
- rewrite apply_total_transf_program.
- rewrite transform_partial_program_compose.
- unfold CSE.transf_program, RTL.program.
- rewrite apply_total_transf_program.
- rewrite transform_partial_program_compose.
- unfold Allocation.transf_program,
- LTL.program, RTL.program.
- rewrite transform_partial_program_compose.
- unfold Tunneling.tunnel_program, LTL.program.
- rewrite apply_total_transf_program.
- rewrite transform_partial_program_compose.
- unfold Linearize.transf_program, LTL.program, Linear.program.
- rewrite apply_total_transf_program.
- rewrite transform_partial_program_compose.
- unfold Stacking.transf_program, Linear.program, Mach.program.
- rewrite transform_partial_program_compose.
- unfold PPCgen.transf_program, Mach.program, PPC.program.
- rewrite transform_partial_program_compose.
- reflexivity.
-Qed.
+(** We prove that the [transf_program] translations preserve semantics.
+ The proof composes the semantic preservation results for each pass.
+ This establishes the correctness of the whole compiler! *)
-(*
-Lemma transf_csharpminor_program_equiv:
- forall p, transf_csharpminor_program2 p = transf_csharpminor_program p.
+Theorem transf_rtl_program_correct:
+ forall p tp beh,
+ transf_rtl_program p = OK tp ->
+ RTL.exec_program p beh ->
+ PPC.exec_program tp beh.
Proof.
- intros.
- unfold transf_csharpminor_program2, transf_csharpminor_program, transf_csharpminor_fundef.
- simpl.
- replace transf_cminor_program2 with transf_cminor_program.
- unfold transf_cminor_program, Cminorgen.transl_program, Cminor.program, PPC.program.
- rewrite apply_partial_transf_program.
- rewrite transform_partial_program2_compose.
- reflexivity.
- symmetry. apply extensionality. exact transf_cminor_program_equiv.
-Qed.
-*)
+ intros. unfold transf_rtl_program, transf_rtl_fundef in H.
+ destruct (transform_partial_program_compose _ _ _ _ _ _ _ _ H) as [p7 [H7 P7]].
+ clear H.
+ destruct (transform_partial_program_compose _ _ _ _ _ _ _ _ H7) as [p6 [H6 P6]].
+ clear H7.
+ destruct (transform_partial_program_compose _ _ _ _ _ _ _ _ H6) as [p5 [H5 P5]].
+ clear H6. generalize (transform_program_partial_program _ _ _ _ _ _ P5). clear P5. intro P5.
+ destruct (transform_partial_program_compose _ _ _ _ _ _ _ _ H5) as [p4 [H4 P4]].
+ clear H5. generalize (transform_program_partial_program _ _ _ _ _ _ P4). clear P4. intro P4.
+ destruct (transform_partial_program_compose _ _ _ _ _ _ _ _ H4) as [p3 [H3 P3]].
+ clear H4. generalize (transform_program_partial_program _ _ _ _ _ _ P3). clear P3. intro P3.
+ destruct (transform_partial_program_compose _ _ _ _ _ _ _ _ H3) as [p2 [H2 P2]].
+ clear H3.
+ destruct (transform_program_compose _ _ _ _ _ _ _ _ H2) as [p1 [H1 P1]].
+ clear H2.
+ destruct (transform_program_compose _ _ _ _ _ _ _ _ H1) as [p0 [H00 P0]].
+ clear H1.
+ generalize (transform_partial_program_identity _ _ _ _ H00). clear H00. intro. subst p0.
-(** * Semantic preservation *)
+ assert (WT3 : LTLtyping.wt_program p3).
+ apply Alloctyping.program_typing_preserved with p2. auto.
+ assert (WT4 : LTLtyping.wt_program p4).
+ subst p4. apply Tunnelingtyping.program_typing_preserved. auto.
+ assert (WT5 : LTLintyping.wt_program p5).
+ subst p5. apply Linearizetyping.program_typing_preserved. auto.
+ assert (WT6 : Lineartyping.wt_program p6).
+ subst p6. apply Reloadtyping.program_typing_preserved. auto.
+ assert (WT7: Machtyping.wt_program p7).
+ apply Stackingtyping.program_typing_preserved with p6. auto. auto.
-(** We prove that the [transf_program] translations preserve semantics. The proof
- composes the semantic preservation results for each pass.
- This establishes the correctness of the whole compiler! *)
+ apply PPCgenproof.transf_program_correct with p7; auto.
+ apply Machabstr2concr.exec_program_equiv; auto.
+ apply Stackingproof.transf_program_correct with p6; auto.
+ subst p6; apply Reloadproof.transf_program_correct; auto.
+ subst p5; apply Linearizeproof.transf_program_correct; auto.
+ subst p4; apply Tunnelingproof.transf_program_correct.
+ apply Allocproof.transf_program_correct with p2; auto.
+ subst p2; apply CSEproof.transf_program_correct.
+ subst p1; apply Constpropproof.transf_program_correct. auto.
+Qed.
Theorem transf_cminor_program_correct:
forall p tp t n,
- transf_cminor_program p = Some tp ->
+ transf_cminor_program p = OK tp ->
Cminor.exec_program p t (Vint n) ->
- PPC.exec_program tp t (Vint n).
+ PPC.exec_program tp (Terminates t n).
Proof.
- intros until n.
- rewrite <- transf_cminor_program_equiv.
- unfold transf_cminor_program2.
- simpl. caseEq (RTLgen.transl_program p). intros p1 EQ1.
- simpl. set (p2 := CSE.transf_program (Constprop.transf_program p1)).
- caseEq (Allocation.transf_program p2). intros p3 EQ3.
- simpl. set (p4 := Tunneling.tunnel_program p3).
- set (p5 := Linearize.transf_program p4).
- caseEq (Stacking.transf_program p5). intros p6 EQ6.
- simpl. intros EQTP EXEC.
- assert (WT3 : LTLtyping.wt_program p3).
- apply Alloctyping.program_typing_preserved with p2. auto.
- assert (WT4 : LTLtyping.wt_program p4).
- unfold p4. apply Tunnelingtyping.program_typing_preserved. auto.
- assert (WT5 : Lineartyping.wt_program p5).
- unfold p5. apply Linearizetyping.program_typing_preserved. auto.
- assert (WT6: Machtyping.wt_program p6).
- apply Stackingtyping.program_typing_preserved with p5. auto. auto.
- apply PPCgenproof.transf_program_correct with p6; auto.
- apply Machabstr2mach.exec_program_equiv; auto.
- apply Stackingproof.transl_program_correct with p5; auto.
- unfold p5; apply Linearizeproof.transf_program_correct.
- unfold p4; apply Tunnelingproof.transf_program_correct.
- apply Allocproof.transl_program_correct with p2; auto.
- unfold p2; apply CSEproof.transf_program_correct;
- apply Constpropproof.transf_program_correct.
- apply RTLgenproof.transl_program_correct with p; auto.
- simpl; intros; discriminate.
- simpl; intros; discriminate.
- simpl; intros; discriminate.
+ intros. unfold transf_cminor_program, transf_cminor_fundef in H.
+ destruct (transform_partial_program_compose _ _ _ _ _ _ _ _ H) as [p3 [H3 P3]].
+ clear H.
+ destruct (transform_partial_program_compose _ _ _ _ _ _ _ _ H3) as [p2 [H2 P2]].
+ clear H3.
+ destruct (transform_program_compose _ _ _ _ _ _ _ _ H2) as [p1 [H1 P1]].
+ generalize (transform_partial_program_identity _ _ _ _ H1). clear H1. intro. subst p1.
+ apply transf_rtl_program_correct with p3. auto.
+ apply RTLgenproof.transl_program_correct with p2; auto.
+ rewrite <- P1. apply Selectionproof.sel_program_correct; auto.
Qed.
Theorem transf_c_program_correct:
forall p tp t n,
- transf_c_program p = Some tp ->
+ transf_c_program p = OK tp ->
Csem.exec_program p t (Vint n) ->
- PPC.exec_program tp t (Vint n).
+ PPC.exec_program tp (Terminates t n).
Proof.
intros until n; unfold transf_c_program; simpl.
caseEq (Ctyping.typecheck_program p); try congruence; intro.
diff --git a/common/Mem.v b/common/Mem.v
index 679c41e..6b66d9d 100644
--- a/common/Mem.v
+++ b/common/Mem.v
@@ -1,11 +1,11 @@
(** This file develops the memory model that is used in the dynamic
- semantics of all the languages of the compiler back-end.
+ semantics of all the languages used in the compiler.
It defines a type [mem] of memory states, the following 4 basic
operations over memory states, and their properties:
-- [alloc]: allocate a fresh memory block;
-- [free]: invalidate a memory block;
- [load]: read a memory chunk at a given address;
-- [store]: store a memory chunk at a given address.
+- [store]: store a memory chunk at a given address;
+- [alloc]: allocate a fresh memory block;
+- [free]: invalidate a memory block.
*)
Require Import Coqlib.
@@ -15,12 +15,6 @@ Require Import Integers.
Require Import Floats.
Require Import Values.
-(** * Structure of memory states *)
-
-(** A memory state is organized in several disjoint blocks. Each block
- has a low and a high bound that defines its size. Each block map
- byte offsets to the contents of this byte. *)
-
Definition update (A: Set) (x: Z) (v: A) (f: Z -> A) : Z -> A :=
fun y => if zeq y x then v else f y.
@@ -40,32 +34,32 @@ Proof.
intros; unfold update. apply zeq_false; auto.
Qed.
+(** * Structure of memory states *)
+
+(** A memory state is organized in several disjoint blocks. Each block
+ has a low and a high bound that defines its size. Each block map
+ byte offsets to the contents of this byte. *)
+
(** The possible contents of a byte-sized memory cell. To give intuitions,
a 4-byte value [v] stored at offset [d] will be represented by
- the content [Datum32 v] at offset [d] and [Cont] at offsets [d+1],
+ the content [Datum(4, v)] at offset [d] and [Cont] at offsets [d+1],
[d+2] and [d+3]. The [Cont] contents enable detecting future writes
- that would overlap partially the 4-byte value. *)
+ that would partially overlap the 4-byte value. *)
Inductive content : Set :=
- | Undef: content (**r undefined contents *)
- | Datum8: val -> content (**r a value that fits in 1 byte *)
- | Datum16: val -> content (**r first byte of a 2-byte value *)
- | Datum32: val -> content (**r first byte of a 4-byte value *)
- | Datum64: val -> content (**r first byte of a 8-byte value *)
- | Cont: content. (**r continuation bytes for a multi-byte value *)
+ | Undef: content (**r undefined contents *)
+ | Datum: nat -> val -> content (**r first byte of a value *)
+ | Cont: content. (**r continuation bytes for a multi-byte value *)
Definition contentmap : Set := Z -> content.
(** A memory block comprises the dimensions of the block (low and high bounds)
- plus a mapping from byte offsets to contents. For technical reasons,
- we also carry around a proof that the mapping is equal to [Undef]
- outside the range of allowed byte offsets. *)
+ plus a mapping from byte offsets to contents. *)
Record block_contents : Set := mkblock {
low: Z;
high: Z;
- contents: contentmap;
- undef_outside: forall ofs, ofs < low \/ ofs >= high -> contents ofs = Undef
+ contents: contentmap
}.
(** A memory state is a mapping from block addresses (represented by [Z]
@@ -82,49 +76,43 @@ Record mem : Set := mkmem {
(** Memory reads and writes are performed by quantities called memory chunks,
encoding the type, size and signedness of the chunk being addressed.
- It is useful to extract only the size information as given by the
- following [memory_size] type. *)
-
-Inductive memory_size : Set :=
- | Size8: memory_size
- | Size16: memory_size
- | Size32: memory_size
- | Size64: memory_size.
-
-Definition size_mem (sz: memory_size) :=
- match sz with
- | Size8 => 1
- | Size16 => 2
- | Size32 => 4
- | Size64 => 8
+ The following functions extract the size information from a chunk. *)
+
+Definition size_chunk (chunk: memory_chunk) : Z :=
+ match chunk with
+ | Mint8signed => 1
+ | Mint8unsigned => 1
+ | Mint16signed => 2
+ | Mint16unsigned => 2
+ | Mint32 => 4
+ | Mfloat32 => 4
+ | Mfloat64 => 8
end.
-Definition mem_chunk (chunk: memory_chunk) :=
+Definition pred_size_chunk (chunk: memory_chunk) : nat :=
match chunk with
- | Mint8signed => Size8
- | Mint8unsigned => Size8
- | Mint16signed => Size16
- | Mint16unsigned => Size16
- | Mint32 => Size32
- | Mfloat32 => Size32
- | Mfloat64 => Size64
+ | Mint8signed => 0%nat
+ | Mint8unsigned => 0%nat
+ | Mint16signed => 1%nat
+ | Mint16unsigned => 1%nat
+ | Mint32 => 3%nat
+ | Mfloat32 => 3%nat
+ | Mfloat64 => 7%nat
end.
-Definition size_chunk (chunk: memory_chunk) := size_mem (mem_chunk chunk).
+Lemma size_chunk_pred:
+ forall chunk, size_chunk chunk = 1 + Z_of_nat (pred_size_chunk chunk).
+Proof.
+ destruct chunk; auto.
+Qed.
(** The initial store. *)
Remark one_pos: 1 > 0.
Proof. omega. Qed.
-Remark undef_undef_outside:
- forall lo hi ofs, ofs < lo \/ ofs >= hi -> (fun y => Undef) ofs = Undef.
-Proof.
- auto.
-Qed.
-
Definition empty_block (lo hi: Z) : block_contents :=
- mkblock lo hi (fun y => Undef) (undef_undef_outside lo hi).
+ mkblock lo hi (fun y => Undef).
Definition empty: mem :=
mkmem (fun x => empty_block 0 0) 1 one_pos.
@@ -200,8 +188,16 @@ Fixpoint check_cont (n: nat) (p: Z) (m: contentmap) {struct n} : bool :=
end
end.
-Definition getN (n: nat) (p: Z) (m: contentmap) : content :=
- if check_cont n (p + 1) m then m p else Undef.
+Definition eq_nat: forall (p q: nat), {p=q} + {p<>q}.
+Proof. decide equality. Defined.
+
+Definition getN (n: nat) (p: Z) (m: contentmap) : val :=
+ match m p with
+ | Datum n' v =>
+ if eq_nat n n' && check_cont n (p + 1) m then v else Vundef
+ | _ =>
+ Vundef
+ end.
Fixpoint set_cont (n: nat) (p: Z) (m: contentmap) {struct n} : contentmap :=
match n with
@@ -209,54 +205,47 @@ Fixpoint set_cont (n: nat) (p: Z) (m: contentmap) {struct n} : contentmap :=
| S n1 => update p Cont (set_cont n1 (p + 1) m)
end.
-Definition setN (n: nat) (p: Z) (v: content) (m: contentmap) : contentmap :=
- update p v (set_cont n (p + 1) m).
+Definition setN (n: nat) (p: Z) (v: val) (m: contentmap) : contentmap :=
+ update p (Datum n v) (set_cont n (p + 1) m).
-Lemma check_cont_true:
- forall n p m,
- (forall q, p <= q < p + Z_of_nat n -> m q = Cont) ->
- check_cont n p m = true.
+Lemma check_cont_spec:
+ forall n m p,
+ if check_cont n p m
+ then (forall q, p <= q < p + Z_of_nat n -> m q = Cont)
+ else (exists q, p <= q < p + Z_of_nat n /\ m q <> Cont).
Proof.
induction n; intros.
- reflexivity.
- simpl. rewrite H. apply IHn.
- intros. apply H. rewrite inj_S. omega.
- rewrite inj_S. omega.
+ simpl. intros; omegaContradiction.
+ simpl check_cont. repeat rewrite inj_S. caseEq (m p); intros.
+ exists p; split. omega. congruence.
+ exists p; split. omega. congruence.
+ generalize (IHn m (p + 1)). case (check_cont n (p + 1) m).
+ intros. assert (p = q \/ p + 1 <= q < p + Zsucc (Z_of_nat n)) by omega.
+ elim H2; intro. congruence. apply H0; omega.
+ intros [q [A B]]. exists q; split. omega. auto.
Qed.
-Hint Resolve check_cont_true.
-
-Lemma check_cont_inv:
- forall n p m,
- check_cont n p m = true ->
- (forall q, p <= q < p + Z_of_nat n -> m q = Cont).
+Lemma check_cont_true:
+ forall n m p,
+ (forall q, p <= q < p + Z_of_nat n -> m q = Cont) ->
+ check_cont n p m = true.
Proof.
- induction n; intros until m.
- unfold Z_of_nat. intros. omegaContradiction.
- unfold check_cont; fold check_cont.
- caseEq (m p); intros; try discriminate.
- assert (p = q \/ p + 1 <= q < (p + 1) + Z_of_nat n).
- rewrite inj_S in H1. omega.
- elim H2; intro.
- subst q. auto.
- apply IHn with (p + 1); auto.
+ intros. generalize (check_cont_spec n m p).
+ destruct (check_cont n p m). auto.
+ intros [q [A B]]. elim B; auto.
Qed.
-Hint Resolve check_cont_inv.
-
Lemma check_cont_false:
- forall n p q m,
- p <= q < p + Z_of_nat n ->
- m q <> Cont ->
+ forall n m p q,
+ p <= q < p + Z_of_nat n -> m q <> Cont ->
check_cont n p m = false.
Proof.
- intros. caseEq (check_cont n p m); intro.
- generalize (check_cont_inv _ _ _ H1 q H). intro. contradiction.
+ intros. generalize (check_cont_spec n m p).
+ destruct (check_cont n p m).
+ intros. elim H0; auto.
auto.
Qed.
-Hint Resolve check_cont_false.
-
Lemma set_cont_inside:
forall n p m q,
p <= q < p + Z_of_nat n ->
@@ -273,8 +262,6 @@ Proof.
red; intro; subst q. omega.
Qed.
-Hint Resolve set_cont_inside.
-
Lemma set_cont_outside:
forall n p m q,
q < p \/ p + Z_of_nat n <= q ->
@@ -286,160 +273,133 @@ Proof.
rewrite update_o. apply IHn. omega. omega.
Qed.
-Hint Resolve set_cont_outside.
-
Lemma getN_setN_same:
forall n p v m,
getN n p (setN n p v m) = v.
Proof.
- intros. unfold getN, setN.
- rewrite check_cont_true. apply update_s.
+ intros. unfold getN, setN. rewrite update_s.
+ rewrite check_cont_true. unfold proj_sumbool.
+ rewrite dec_eq_true. auto.
intros. rewrite update_o. apply set_cont_inside. auto.
omega.
Qed.
-Hint Resolve getN_setN_same.
-
Lemma getN_setN_other:
forall n1 n2 p1 p2 v m,
p1 + Z_of_nat n1 < p2 \/ p2 + Z_of_nat n2 < p1 ->
getN n2 p2 (setN n1 p1 v m) = getN n2 p2 m.
Proof.
intros. unfold getN, setN.
- caseEq (check_cont n2 (p2 + 1) m); intro.
- rewrite check_cont_true. rewrite update_o.
- apply set_cont_outside. omega. omega.
- intros. rewrite update_o. rewrite set_cont_outside.
- eapply check_cont_inv. eauto. auto.
+ generalize (check_cont_spec n2 m (p2 + 1));
+ destruct (check_cont n2 (p2 + 1) m); intros.
+ rewrite check_cont_true.
+ rewrite update_o. rewrite set_cont_outside. auto.
omega. omega.
- caseEq (check_cont n2 (p2 + 1) (update p1 v (set_cont n1 (p1 + 1) m))); intros.
- assert (check_cont n2 (p2 + 1) m = true).
- apply check_cont_true. intros.
- generalize (check_cont_inv _ _ _ H1 q H2).
- rewrite update_o. rewrite set_cont_outside. auto. omega. omega.
- rewrite H0 in H2; discriminate.
- auto.
-Qed.
-
-Hint Resolve getN_setN_other.
+ intros. rewrite update_o. rewrite set_cont_outside. auto.
+ omega. omega.
+ destruct H0 as [q [A B]].
+ rewrite (check_cont_false n2 (update p1 (Datum n1 v) (set_cont n1 (p1 + 1) m)) (p2 + 1) q).
+ rewrite update_o. rewrite set_cont_outside. auto.
+ omega. omega. omega.
+ rewrite update_o. rewrite set_cont_outside. auto.
+ omega. omega.
+Qed.
Lemma getN_setN_overlap:
forall n1 n2 p1 p2 v m,
p1 <> p2 ->
p1 + Z_of_nat n1 >= p2 -> p2 + Z_of_nat n2 >= p1 ->
- v <> Cont ->
- getN n2 p2 (setN n1 p1 v m) = Cont \/
- getN n2 p2 (setN n1 p1 v m) = Undef.
-Proof.
- intros. unfold getN.
- caseEq (check_cont n2 (p2 + 1) (setN n1 p1 v m)); intro.
- case (zlt p2 p1); intro.
- assert (p2 + 1 <= p1 < p2 + 1 + Z_of_nat n2). omega.
- generalize (check_cont_inv _ _ _ H3 p1 H4).
- unfold setN. rewrite update_s. intro. contradiction.
- left. unfold setN. rewrite update_o.
- apply set_cont_inside. omega. auto.
- right; auto.
-Qed.
-
-Hint Resolve getN_setN_overlap.
+ getN n2 p2 (setN n1 p1 v m) = Vundef.
+Proof.
+ intros. unfold getN, setN.
+ rewrite update_o; auto.
+ destruct (zlt p2 p1).
+ (* [p1] belongs to [[p2, p2 + n2 - 1]],
+ therefore [check_cont n2 (p2 + 1) ...] is false. *)
+ rewrite (check_cont_false n2 (update p1 (Datum n1 v) (set_cont n1 (p1 + 1) m)) (p2 + 1) p1).
+ destruct (set_cont n1 (p1 + 1) m p2); auto.
+ destruct (eq_nat n2 n); auto.
+ omega.
+ rewrite update_s. congruence.
+ (* [p2] belongs to [[p1 + 1, p1 + n1 - 1]],
+ therefore [set_cont n1 (p1 + 1) m p2] is [Cont]. *)
+ rewrite set_cont_inside. auto. omega.
+Qed.
Lemma getN_setN_mismatch:
forall n1 n2 p v m,
- getN n2 p (setN n1 p v m) = v \/ getN n2 p (setN n1 p v m) = Undef.
+ n1 <> n2 ->
+ getN n2 p (setN n1 p v m) = Vundef.
Proof.
- intros. unfold getN.
- caseEq (check_cont n2 (p + 1) (setN n1 p v m)); intro.
- left. unfold setN. apply update_s.
- right. auto.
+ intros. unfold getN, setN. rewrite update_s.
+ unfold proj_sumbool; rewrite dec_eq_false; simpl. auto. auto.
Qed.
-Hint Resolve getN_setN_mismatch.
+Lemma getN_setN_characterization:
+ forall m v n1 p1 n2 p2,
+ getN n2 p2 (setN n1 p1 v m) = v
+ \/ getN n2 p2 (setN n1 p1 v m) = getN n2 p2 m
+ \/ getN n2 p2 (setN n1 p1 v m) = Vundef.
+Proof.
+ intros. destruct (zeq p1 p2). subst p2.
+ destruct (eq_nat n1 n2). subst n2.
+ left; apply getN_setN_same.
+ right; right; apply getN_setN_mismatch; auto.
+ destruct (zlt (p1 + Z_of_nat n1) p2).
+ right; left; apply getN_setN_other; auto.
+ destruct (zlt (p2 + Z_of_nat n2) p1).
+ right; left; apply getN_setN_other; auto.
+ right; right; apply getN_setN_overlap; omega.
+Qed.
Lemma getN_init:
forall n p,
- getN n p (fun y => Undef) = Undef.
+ getN n p (fun y => Undef) = Vundef.
Proof.
- intros. unfold getN.
- case (check_cont n (p + 1) (fun y => Undef)); auto.
+ intros. auto.
Qed.
-Hint Resolve getN_init.
+(** [valid_access m chunk b ofs] holds if a memory access (load or store)
+ of the given chunk is possible in [m] at address [b, ofs]. *)
+
+Inductive valid_access (m: mem) (chunk: memory_chunk) (b: block) (ofs: Z) : Prop :=
+ | valid_access_intro:
+ valid_block m b ->
+ low_bound m b <= ofs ->
+ ofs + size_chunk chunk <= high_bound m b ->
+ valid_access m chunk b ofs.
(** The following function checks whether accessing the given memory chunk
at the given offset in the given block respects the bounds of the block. *)
-Definition in_bounds (chunk: memory_chunk) (ofs: Z) (c: block_contents) :
- {c.(low) <= ofs /\ ofs + size_chunk chunk <= c.(high)}
- + {c.(low) > ofs \/ ofs + size_chunk chunk > c.(high)} :=
- match zle c.(low) ofs, zle (ofs + size_chunk chunk) c.(high) with
- | left P1, left P2 => left _ (conj P1 P2)
- | left P1, right P2 => right _ (or_intror _ P2)
- | right P1, _ => right _ (or_introl _ P1)
- end.
-
-Lemma in_bounds_holds:
- forall (chunk: memory_chunk) (ofs: Z) (c: block_contents)
- (A: Set) (a b: A),
- c.(low) <= ofs -> ofs + size_chunk chunk <= c.(high) ->
- (if in_bounds chunk ofs c then a else b) = a.
+Definition in_bounds (m: mem) (chunk: memory_chunk) (b: block) (ofs: Z) :
+ {valid_access m chunk b ofs} + {~valid_access m chunk b ofs}.
Proof.
- intros. case (in_bounds chunk ofs c); intro.
- auto.
- omegaContradiction.
-Qed.
+ intros.
+ destruct (zlt b m.(nextblock)).
+ destruct (zle (low_bound m b) ofs).
+ destruct (zle (ofs + size_chunk chunk) (high_bound m b)).
+ left; constructor; auto.
+ right; red; intro V; inv V; omega.
+ right; red; intro V; inv V; omega.
+ right; red; intro V; inv V; contradiction.
+Defined.
-Lemma in_bounds_exten:
- forall (chunk: memory_chunk) (ofs: Z) (c: block_contents) (x: contentmap) P,
- in_bounds chunk ofs (mkblock (low c) (high c) x P) =
- in_bounds chunk ofs c.
+Lemma in_bounds_true:
+ forall m chunk b ofs (A: Set) (a1 a2: A),
+ valid_access m chunk b ofs ->
+ (if in_bounds m chunk b ofs then a1 else a2) = a1.
Proof.
- intros; reflexivity.
+ intros. destruct (in_bounds m chunk b ofs). auto. contradiction.
Qed.
-Hint Resolve in_bounds_holds in_bounds_exten.
-
(** [valid_pointer] holds if the given block address is valid and the
given offset falls within the bounds of the corresponding block. *)
Definition valid_pointer (m: mem) (b: block) (ofs: Z) : bool :=
- if zlt b m.(nextblock) then
- (let c := m.(blocks) b in
- if zle c.(low) ofs then if zlt ofs c.(high) then true else false
- else false)
- else false.
-
-(** Read a quantity of size [sz] at offset [ofs] in block contents [c].
- Return [Vundef] if the requested size does not match that of the
- current contents, or if the following offsets do not contain [Cont].
- The first check captures a size mismatch between the read and the
- latest write at this offset. The second check captures partial overwriting
- of the latest write at this offset by a more recent write at a nearby
- offset. *)
-
-Definition load_contents (sz: memory_size) (c: contentmap) (ofs: Z) : val :=
- match sz with
- | Size8 =>
- match getN 0%nat ofs c with
- | Datum8 n => n
- | _ => Vundef
- end
- | Size16 =>
- match getN 1%nat ofs c with
- | Datum16 n => n
- | _ => Vundef
- end
- | Size32 =>
- match getN 3%nat ofs c with
- | Datum32 n => n
- | _ => Vundef
- end
- | Size64 =>
- match getN 7%nat ofs c with
- | Datum64 n => n
- | _ => Vundef
- end
- end.
+ zlt b m.(nextblock) &&
+ zle (low_bound m b) ofs &&
+ zlt ofs (high_bound m b).
(** [load chunk m b ofs] perform a read in memory state [m], at address
[b] and offset [ofs]. [None] is returned if the address is invalid
@@ -447,15 +407,25 @@ Definition load_contents (sz: memory_size) (c: contentmap) (ofs: Z) : val :=
Definition load (chunk: memory_chunk) (m: mem) (b: block) (ofs: Z)
: option val :=
- if zlt b m.(nextblock) then
- (let c := m.(blocks) b in
- if in_bounds chunk ofs c
- then Some (Val.load_result chunk
- (load_contents (mem_chunk chunk) c.(contents) ofs))
- else None)
+ if in_bounds m chunk b ofs then
+ Some (Val.load_result chunk
+ (getN (pred_size_chunk chunk) ofs (contents (blocks m b))))
else
None.
+Lemma load_inv:
+ forall chunk m b ofs v,
+ load chunk m b ofs = Some v ->
+ valid_access m chunk b ofs /\
+ v = Val.load_result chunk
+ (getN (pred_size_chunk chunk) ofs (contents (blocks m b))).
+Proof.
+ intros until v; unfold load.
+ destruct (in_bounds m chunk b ofs); intros.
+ split. auto. congruence.
+ congruence.
+Qed.
+
(** [loadv chunk m addr] is similar, but the address and offset are given
as a single value [addr], which must be a pointer value. *)
@@ -465,90 +435,17 @@ Definition loadv (chunk: memory_chunk) (m: mem) (addr: val) : option val :=
| _ => None
end.
-Theorem load_in_bounds:
- forall (chunk: memory_chunk) (m: mem) (b: block) (ofs: Z),
- valid_block m b ->
- low_bound m b <= ofs ->
- ofs + size_chunk chunk <= high_bound m b ->
- exists v, load chunk m b ofs = Some v.
-Proof.
- intros. unfold load. rewrite zlt_true; auto.
- rewrite in_bounds_holds.
- exists (Val.load_result chunk
- (load_contents (mem_chunk chunk)
- (contents (m.(blocks) b))
- ofs)).
- auto.
- exact H0. exact H1.
-Qed.
-
-Lemma load_inv:
- forall (chunk: memory_chunk) (m: mem) (b: block) (ofs: Z) (v: val),
- load chunk m b ofs = Some v ->
- let c := m.(blocks) b in
- b < m.(nextblock) /\
- c.(low) <= ofs /\
- ofs + size_chunk chunk <= c.(high) /\
- Val.load_result chunk (load_contents (mem_chunk chunk) c.(contents) ofs) = v.
-Proof.
- intros until v; unfold load.
- case (zlt b (nextblock m)); intro.
- set (c := m.(blocks) b).
- case (in_bounds chunk ofs c).
- intuition congruence.
- intros; discriminate.
- intros; discriminate.
-Qed.
-Hint Resolve load_in_bounds load_inv.
-
-(* Write the value [v] with size [sz] at offset [ofs] in block contents [c].
- Return updated block contents. [Cont] contents are stored at the following
- offsets. *)
-
-Definition store_contents (sz: memory_size) (c: contentmap)
- (ofs: Z) (v: val) : contentmap :=
- match sz with
- | Size8 =>
- setN 0%nat ofs (Datum8 v) c
- | Size16 =>
- setN 1%nat ofs (Datum16 v) c
- | Size32 =>
- setN 3%nat ofs (Datum32 v) c
- | Size64 =>
- setN 7%nat ofs (Datum64 v) c
- end.
-
-Remark store_contents_undef_outside:
- forall sz c ofs v lo hi,
- lo <= ofs /\ ofs + size_mem sz <= hi ->
- (forall x, x < lo \/ x >= hi -> c x = Undef) ->
- (forall x, x < lo \/ x >= hi ->
- store_contents sz c ofs v x = Undef).
-Proof.
- intros until hi; intros [LO HI] UO.
- assert (forall n d x,
- ofs + (1 + Z_of_nat n) <= hi ->
- x < lo \/ x >= hi ->
- setN n ofs d c x = Undef).
- intros. unfold setN. rewrite update_o.
- transitivity (c x). apply set_cont_outside. omega.
- apply UO. omega. omega.
- unfold store_contents; destruct sz; unfold size_mem in HI;
- intros; apply H; auto; simpl Z_of_nat; auto.
-Qed.
+(* The memory state [m] after a store of value [v] at offset [ofs]
+ in block [b]. *)
Definition unchecked_store
(chunk: memory_chunk) (m: mem) (b: block)
- (ofs: Z) (v: val)
- (P: (m.(blocks) b).(low) <= ofs /\
- ofs + size_chunk chunk <= (m.(blocks) b).(high)) : mem :=
+ (ofs: Z) (v: val) : mem :=
let c := m.(blocks) b in
mkmem
(update b
(mkblock c.(low) c.(high)
- (store_contents (mem_chunk chunk) c.(contents) ofs v)
- (store_contents_undef_outside (mem_chunk chunk) c.(contents)
- ofs v _ _ P c.(undef_outside)))
+ (setN (pred_size_chunk chunk) ofs v c.(contents)))
m.(blocks))
m.(nextblock)
m.(nextblock_pos).
@@ -560,13 +457,21 @@ Definition unchecked_store
Definition store (chunk: memory_chunk) (m: mem) (b: block)
(ofs: Z) (v: val) : option mem :=
- if zlt b m.(nextblock) then
- match in_bounds chunk ofs (m.(blocks) b) with
- | left P => Some(unchecked_store chunk m b ofs v P)
- | right _ => None
- end
- else
- None.
+ if in_bounds m chunk b ofs
+ then Some(unchecked_store chunk m b ofs v)
+ else None.
+
+Lemma store_inv:
+ forall chunk m b ofs v m',
+ store chunk m b ofs v = Some m' ->
+ valid_access m chunk b ofs /\
+ m' = unchecked_store chunk m b ofs v.
+Proof.
+ intros until m'; unfold store.
+ destruct (in_bounds m chunk b ofs); intros.
+ split. auto. congruence.
+ congruence.
+Qed.
(** [storev chunk m addr v] is similar, but the address and offset are given
as a single value [addr], which must be a pointer value. *)
@@ -577,63 +482,21 @@ Definition storev (chunk: memory_chunk) (m: mem) (addr v: val) : option mem :=
| _ => None
end.
-Theorem store_in_bounds:
- forall (chunk: memory_chunk) (m: mem) (b: block) (ofs: Z) (v: val),
- valid_block m b ->
- low_bound m b <= ofs ->
- ofs + size_chunk chunk <= high_bound m b ->
- exists m', store chunk m b ofs v = Some m'.
-Proof.
- intros. unfold store.
- rewrite zlt_true; auto.
- case (in_bounds chunk ofs (blocks m b)); intro P.
- exists (unchecked_store chunk m b ofs v P). reflexivity.
- unfold low_bound in H0. unfold high_bound in H1. omegaContradiction.
-Qed.
-
-Lemma store_inv:
- forall (chunk: memory_chunk) (m m': mem) (b: block) (ofs: Z) (v: val),
- store chunk m b ofs v = Some m' ->
- let c := m.(blocks) b in
- b < m.(nextblock) /\
- c.(low) <= ofs /\
- ofs + size_chunk chunk <= c.(high) /\
- m'.(nextblock) = m.(nextblock) /\
- exists P, m'.(blocks) =
- update b (mkblock c.(low) c.(high)
- (store_contents (mem_chunk chunk) c.(contents) ofs v) P)
- m.(blocks).
-Proof.
- intros until v; unfold store.
- case (zlt b (nextblock m)); intro.
- set (c := m.(blocks) b).
- case (in_bounds chunk ofs c).
- intros; injection H; intro; subst m'. simpl.
- intuition. fold c.
- exists (store_contents_undef_outside (mem_chunk chunk)
- (contents c) ofs v (low c) (high c) a (undef_outside c)).
- auto.
- intros; discriminate.
- intros; discriminate.
-Qed.
-
-Hint Resolve store_in_bounds store_inv.
-
(** Build a block filled with the given initialization data. *)
Fixpoint contents_init_data (pos: Z) (id: list init_data) {struct id}: contentmap :=
match id with
| nil => (fun y => Undef)
| Init_int8 n :: id' =>
- store_contents Size8 (contents_init_data (pos + 1) id') pos (Vint n)
+ setN 0%nat pos (Vint n) (contents_init_data (pos + 1) id')
| Init_int16 n :: id' =>
- store_contents Size16 (contents_init_data (pos + 2) id') pos (Vint n)
+ setN 1%nat pos (Vint n) (contents_init_data (pos + 1) id')
| Init_int32 n :: id' =>
- store_contents Size32 (contents_init_data (pos + 4) id') pos (Vint n)
+ setN 3%nat pos (Vint n) (contents_init_data (pos + 1) id')
| Init_float32 f :: id' =>
- store_contents Size32 (contents_init_data (pos + 4) id') pos (Vfloat f)
+ setN 3%nat pos (Vfloat f) (contents_init_data (pos + 1) id')
| Init_float64 f :: id' =>
- store_contents Size64 (contents_init_data (pos + 8) id') pos (Vfloat f)
+ setN 7%nat pos (Vfloat f) (contents_init_data (pos + 1) id')
| Init_space n :: id' =>
contents_init_data (pos + Zmax n 0) id'
| Init_pointer x :: id' =>
@@ -664,32 +527,8 @@ Proof.
generalize (Zmax2 z 0). omega. omega.
Qed.
-Remark contents_init_data_undef_outside:
- forall id pos x,
- x < pos \/ x >= pos + size_init_data_list id ->
- contents_init_data pos id x = Undef.
-Proof.
- induction id; simpl; intros.
- auto.
- generalize (size_init_data_list_pos id); intro.
- assert (forall n delta dt,
- delta = 1 + Z_of_nat n ->
- x < pos \/ x >= pos + (delta + size_init_data_list id) ->
- setN n pos dt (contents_init_data (pos + delta) id) x = Undef).
- intros. unfold setN. rewrite update_o.
- transitivity (contents_init_data (pos + delta) id x).
- apply set_cont_outside. omega.
- apply IHid. omega. omega.
- unfold size_init_data in H; destruct a;
- try (apply H1; [reflexivity|assumption]).
- apply IHid. generalize (Zmax2 z 0). omega.
- apply IHid. omega.
-Qed.
-
Definition block_init_data (id: list init_data) : block_contents :=
- mkblock 0 (size_init_data_list id)
- (contents_init_data 0 id)
- (contents_init_data_undef_outside id 0).
+ mkblock 0 (size_init_data_list id) (contents_init_data 0 id).
Definition alloc_init_data (m: mem) (id: list init_data) : mem * block :=
(mkmem (update m.(nextblock)
@@ -702,8 +541,7 @@ Definition alloc_init_data (m: mem) (id: list init_data) : mem * block :=
Remark block_init_data_empty:
block_init_data nil = empty_block 0 0.
Proof.
- unfold block_init_data, empty_block. simpl.
- decEq. apply proof_irrelevance.
+ auto.
Qed.
(** * Properties of the memory operations *)
@@ -716,573 +554,961 @@ Proof.
intros; red; intros. subst b'. contradiction.
Qed.
-Theorem fresh_block_alloc:
- forall (m1 m2: mem) (lo hi: Z) (b: block),
- alloc m1 lo hi = (m2, b) -> ~(valid_block m1 b).
+Lemma valid_access_valid_block:
+ forall m chunk b ofs,
+ valid_access m chunk b ofs -> valid_block m b.
Proof.
- intros. injection H; intros; subst b.
- unfold valid_block. omega.
+ intros. inv H; auto.
Qed.
-Theorem valid_new_block:
- forall (m1 m2: mem) (lo hi: Z) (b: block),
- alloc m1 lo hi = (m2, b) -> valid_block m2 b.
+Hint Resolve valid_not_valid_diff valid_access_valid_block: mem.
+
+(** ** Properties related to [load] *)
+
+Theorem valid_access_load:
+ forall m chunk b ofs,
+ valid_access m chunk b ofs ->
+ exists v, load chunk m b ofs = Some v.
Proof.
- unfold alloc, valid_block; intros.
- injection H; intros. subst b; subst m2; simpl. omega.
+ intros. econstructor. unfold load. rewrite in_bounds_true; auto.
Qed.
-Theorem valid_block_alloc:
- forall (m1 m2: mem) (lo hi: Z) (b b': block),
- alloc m1 lo hi = (m2, b') ->
- valid_block m1 b -> valid_block m2 b.
+Theorem load_valid_access:
+ forall m chunk b ofs v,
+ load chunk m b ofs = Some v ->
+ valid_access m chunk b ofs.
Proof.
- unfold alloc, valid_block; intros.
- injection H; intros. subst m2; simpl. omega.
+ intros. generalize (load_inv _ _ _ _ _ H). tauto.
Qed.
-Theorem valid_block_store:
- forall (chunk: memory_chunk) (m1 m2: mem) (b b': block) (ofs: Z) (v: val),
- store chunk m1 b' ofs v = Some m2 ->
- valid_block m1 b -> valid_block m2 b.
+Hint Resolve load_valid_access valid_access_load.
+
+(** ** Properties related to [store] *)
+
+Lemma valid_access_store:
+ forall m1 chunk b ofs v,
+ valid_access m1 chunk b ofs ->
+ exists m2, store chunk m1 b ofs v = Some m2.
Proof.
- intros. generalize (store_inv _ _ _ _ _ _ H).
- intros [A [B [C [D [P E]]]]].
- red. rewrite D. exact H0.
+ intros. econstructor. unfold store. rewrite in_bounds_true; auto.
Qed.
-Theorem valid_block_free:
- forall (m: mem) (b b': block),
- valid_block m b -> valid_block (free m b') b.
+Hint Resolve valid_access_store: mem.
+
+Section STORE.
+Variable chunk: memory_chunk.
+Variable m1: mem.
+Variable b: block.
+Variable ofs: Z.
+Variable v: val.
+Variable m2: mem.
+Hypothesis STORE: store chunk m1 b ofs v = Some m2.
+
+Lemma low_bound_store:
+ forall b', low_bound m2 b' = low_bound m1 b'.
Proof.
- unfold valid_block, free; intros.
- simpl. auto.
+ intro. elim (store_inv _ _ _ _ _ _ STORE); intros.
+ subst m2. unfold low_bound, unchecked_store; simpl.
+ unfold update. destruct (zeq b' b); auto. subst b'; auto.
+Qed.
+
+Lemma high_bound_store:
+ forall b', high_bound m2 b' = high_bound m1 b'.
+Proof.
+ intro. elim (store_inv _ _ _ _ _ _ STORE); intros.
+ subst m2. unfold high_bound, unchecked_store; simpl.
+ unfold update. destruct (zeq b' b); auto. subst b'; auto.
Qed.
-(** ** Properties related to [alloc] *)
+Lemma nextblock_store:
+ nextblock m2 = nextblock m1.
+Proof.
+ intros. elim (store_inv _ _ _ _ _ _ STORE); intros.
+ subst m2; reflexivity.
+Qed.
-Theorem load_alloc_other:
- forall (chunk: memory_chunk) (m1 m2: mem)
- (b b': block) (ofs lo hi: Z) (v: val),
- alloc m1 lo hi = (m2, b') ->
- load chunk m1 b ofs = Some v ->
- load chunk m2 b ofs = Some v.
+Lemma store_valid_block_1:
+ forall b', valid_block m1 b' -> valid_block m2 b'.
Proof.
- unfold alloc; intros.
- injection H; intros; subst m2; clear H.
- generalize (load_inv _ _ _ _ _ H0).
- intros (A, (B, (C, D))).
- unfold load; simpl.
- rewrite zlt_true.
- repeat (rewrite update_o).
- rewrite in_bounds_holds. congruence. auto. auto.
- omega. omega.
+ unfold valid_block; intros. rewrite nextblock_store; auto.
Qed.
-Lemma load_contents_init:
- forall (sz: memory_size) (ofs: Z),
- load_contents sz (fun y => Undef) ofs = Vundef.
+Lemma store_valid_block_2:
+ forall b', valid_block m2 b' -> valid_block m1 b'.
Proof.
- intros. destruct sz; reflexivity.
+ unfold valid_block; intros. rewrite nextblock_store in H; auto.
Qed.
-Theorem load_alloc_same:
- forall (chunk: memory_chunk) (m1 m2: mem)
- (b b': block) (ofs lo hi: Z) (v: val),
- alloc m1 lo hi = (m2, b') ->
- load chunk m2 b' ofs = Some v ->
- v = Vundef.
+Hint Resolve store_valid_block_1 store_valid_block_2: mem.
+
+Lemma store_valid_access_1:
+ forall chunk' b' ofs',
+ valid_access m1 chunk' b' ofs' -> valid_access m2 chunk' b' ofs'.
Proof.
- unfold alloc; intros.
- injection H; intros; subst m2; clear H.
- generalize (load_inv _ _ _ _ _ H0).
- simpl. rewrite H1. rewrite update_s. simpl. intros (A, (B, (C, D))).
- rewrite <- D. rewrite load_contents_init.
- destruct chunk; reflexivity.
-Qed.
+ intros. inv H. constructor. auto with mem.
+ rewrite low_bound_store; auto.
+ rewrite high_bound_store; auto.
+Qed.
-Theorem low_bound_alloc:
- forall (m1 m2: mem) (b b': block) (lo hi: Z),
- alloc m1 lo hi = (m2, b') ->
- low_bound m2 b = if zeq b b' then lo else low_bound m1 b.
+Lemma store_valid_access_2:
+ forall chunk' b' ofs',
+ valid_access m2 chunk' b' ofs' -> valid_access m1 chunk' b' ofs'.
Proof.
- unfold alloc; intros.
- injection H; intros; subst m2; clear H.
- unfold low_bound; simpl.
- unfold update.
- subst b'.
- case (zeq b (nextblock m1)); reflexivity.
+ intros. inv H. constructor. auto with mem.
+ rewrite low_bound_store in H1; auto.
+ rewrite high_bound_store in H2; auto.
Qed.
-Theorem high_bound_alloc:
- forall (m1 m2: mem) (b b': block) (lo hi: Z),
- alloc m1 lo hi = (m2, b') ->
- high_bound m2 b = if zeq b b' then hi else high_bound m1 b.
+Lemma store_valid_access_3:
+ valid_access m1 chunk b ofs.
Proof.
- unfold alloc; intros.
- injection H; intros; subst m2; clear H.
- unfold high_bound; simpl.
- unfold update.
- subst b'.
- case (zeq b (nextblock m1)); reflexivity.
+ elim (store_inv _ _ _ _ _ _ STORE); intros. auto.
Qed.
-Theorem store_alloc:
- forall (chunk: memory_chunk) (m1 m2: mem) (b: block) (ofs lo hi: Z) (v: val),
- alloc m1 lo hi = (m2, b) ->
- lo <= ofs -> ofs + size_chunk chunk <= hi ->
- exists m2', store chunk m2 b ofs v = Some m2'.
+Hint Resolve store_valid_access_1 store_valid_access_2
+ store_valid_access_3: mem.
+
+Theorem load_store_similar:
+ forall chunk',
+ size_chunk chunk' = size_chunk chunk ->
+ load chunk' m2 b ofs = Some (Val.load_result chunk' v).
Proof.
- unfold alloc; intros.
- injection H; intros.
- assert (A: b < m2.(nextblock)).
- subst m2; subst b; simpl; omega.
- assert (B: low_bound m2 b <= ofs).
- subst m2; subst b. unfold low_bound; simpl. rewrite update_s.
- simpl. assumption.
- assert (C: ofs + size_chunk chunk <= high_bound m2 b).
- subst m2; subst b. unfold high_bound; simpl. rewrite update_s.
- simpl. assumption.
- exact (store_in_bounds chunk m2 b ofs v A B C).
+ intros. destruct (store_inv _ _ _ _ _ _ STORE).
+ unfold load. rewrite in_bounds_true.
+ decEq. decEq. rewrite H1. unfold unchecked_store; simpl.
+ rewrite update_s. simpl.
+ replace (pred_size_chunk chunk) with (pred_size_chunk chunk').
+ apply getN_setN_same.
+ repeat rewrite size_chunk_pred in H. omega.
+ apply store_valid_access_1.
+ inv H0. constructor; auto. congruence.
Qed.
-Hint Resolve store_alloc high_bound_alloc low_bound_alloc load_alloc_same
-load_contents_init load_alloc_other.
+Theorem load_store_same:
+ load chunk m2 b ofs = Some (Val.load_result chunk v).
+Proof.
+ eapply load_store_similar; eauto.
+Qed.
+
+Theorem load_store_other:
+ forall chunk' b' ofs',
+ b' <> b
+ \/ ofs' + size_chunk chunk' <= ofs
+ \/ ofs + size_chunk chunk <= ofs' ->
+ load chunk' m2 b' ofs' = load chunk' m1 b' ofs'.
+Proof.
+ intros. destruct (store_inv _ _ _ _ _ _ STORE).
+ unfold load. destruct (in_bounds m1 chunk' b' ofs').
+ rewrite in_bounds_true. decEq. decEq.
+ rewrite H1; unfold unchecked_store; simpl.
+ unfold update. destruct (zeq b' b). subst b'.
+ simpl. repeat rewrite size_chunk_pred in H.
+ apply getN_setN_other. elim H; intro. congruence. omega.
+ auto.
+ eauto with mem.
+ destruct (in_bounds m2 chunk' b' ofs'); auto.
+ elim n. eauto with mem.
+Qed.
+
+Theorem load_store_overlap:
+ forall chunk' ofs' v',
+ load chunk' m2 b ofs' = Some v' ->
+ ofs' <> ofs ->
+ ofs' + size_chunk chunk' > ofs ->
+ ofs + size_chunk chunk > ofs' ->
+ v' = Vundef.
+Proof.
+ intros. destruct (store_inv _ _ _ _ _ _ STORE).
+ destruct (load_inv _ _ _ _ _ H). rewrite H6.
+ rewrite H4. unfold unchecked_store. simpl. rewrite update_s.
+ simpl. rewrite getN_setN_overlap.
+ destruct chunk'; reflexivity.
+ auto. rewrite size_chunk_pred in H2. omega.
+ rewrite size_chunk_pred in H1. omega.
+Qed.
+
+Theorem load_store_overlap':
+ forall chunk' ofs',
+ valid_access m1 chunk' b ofs' ->
+ ofs' <> ofs ->
+ ofs' + size_chunk chunk' > ofs ->
+ ofs + size_chunk chunk > ofs' ->
+ load chunk' m2 b ofs' = Some Vundef.
+Proof.
+ intros.
+ assert (exists v', load chunk' m2 b ofs' = Some v').
+ eauto with mem.
+ destruct H3 as [v' LOAD]. rewrite LOAD. decEq.
+ eapply load_store_overlap; eauto.
+Qed.
-(** ** Properties related to [free] *)
+Theorem load_store_mismatch:
+ forall chunk' v',
+ load chunk' m2 b ofs = Some v' ->
+ size_chunk chunk' <> size_chunk chunk ->
+ v' = Vundef.
+Proof.
+ intros. destruct (store_inv _ _ _ _ _ _ STORE).
+ destruct (load_inv _ _ _ _ _ H). rewrite H4.
+ rewrite H2. unfold unchecked_store. simpl. rewrite update_s.
+ simpl. rewrite getN_setN_mismatch.
+ destruct chunk'; reflexivity.
+ repeat rewrite size_chunk_pred in H0; omega.
+Qed.
-Theorem load_free:
- forall (chunk: memory_chunk) (m: mem) (b bf: block) (ofs: Z),
- b <> bf ->
- load chunk (free m bf) b ofs = load chunk m b ofs.
+Theorem load_store_mismatch':
+ forall chunk',
+ valid_access m1 chunk' b ofs ->
+ size_chunk chunk' <> size_chunk chunk ->
+ load chunk' m2 b ofs = Some Vundef.
Proof.
- intros. unfold free, load; simpl.
- case (zlt b (nextblock m)).
- repeat (rewrite update_o; auto).
- reflexivity.
+ intros.
+ assert (exists v', load chunk' m2 b ofs = Some v').
+ eauto with mem.
+ destruct H1 as [v' LOAD]. rewrite LOAD. decEq.
+ eapply load_store_mismatch; eauto.
+Qed.
+
+Inductive load_store_cases
+ (chunk1: memory_chunk) (b1: block) (ofs1: Z)
+ (chunk2: memory_chunk) (b2: block) (ofs2: Z) : Set :=
+ | lsc_similar:
+ b1 = b2 -> ofs1 = ofs2 -> size_chunk chunk1 = size_chunk chunk2 ->
+ load_store_cases chunk1 b1 ofs1 chunk2 b2 ofs2
+ | lsc_other:
+ b1 <> b2 \/ ofs2 + size_chunk chunk2 <= ofs1 \/ ofs1 + size_chunk chunk1 <= ofs2 ->
+ load_store_cases chunk1 b1 ofs1 chunk2 b2 ofs2
+ | lsc_overlap:
+ b1 = b2 -> ofs1 <> ofs2 -> ofs2 + size_chunk chunk2 > ofs1 -> ofs1 + size_chunk chunk1 > ofs2 ->
+ load_store_cases chunk1 b1 ofs1 chunk2 b2 ofs2
+ | lsc_mismatch:
+ b1 = b2 -> ofs1 = ofs2 -> size_chunk chunk1 <> size_chunk chunk2 ->
+ load_store_cases chunk1 b1 ofs1 chunk2 b2 ofs2.
+
+Remark size_chunk_pos:
+ forall chunk1, size_chunk chunk1 > 0.
+Proof.
+ destruct chunk1; simpl; omega.
+Qed.
+
+Definition load_store_classification:
+ forall (chunk1: memory_chunk) (b1: block) (ofs1: Z)
+ (chunk2: memory_chunk) (b2: block) (ofs2: Z),
+ load_store_cases chunk1 b1 ofs1 chunk2 b2 ofs2.
+Proof.
+ intros. destruct (eq_block b1 b2).
+ destruct (zeq ofs1 ofs2).
+ destruct (zeq (size_chunk chunk1) (size_chunk chunk2)).
+ apply lsc_similar; auto.
+ apply lsc_mismatch; auto.
+ destruct (zle (ofs2 + size_chunk chunk2) ofs1).
+ apply lsc_other. tauto.
+ destruct (zle (ofs1 + size_chunk chunk1) ofs2).
+ apply lsc_other. tauto.
+ apply lsc_overlap; auto.
+ apply lsc_other; tauto.
+Qed.
+
+Theorem load_store_characterization:
+ forall chunk' b' ofs',
+ valid_access m1 chunk' b' ofs' ->
+ load chunk' m2 b' ofs' =
+ match load_store_classification chunk b ofs chunk' b' ofs' with
+ | lsc_similar _ _ _ => Some (Val.load_result chunk' v)
+ | lsc_other _ => load chunk' m1 b' ofs'
+ | lsc_overlap _ _ _ _ => Some Vundef
+ | lsc_mismatch _ _ _ => Some Vundef
+ end.
+Proof.
+ intros.
+ assert (exists v', load chunk' m2 b' ofs' = Some v') by eauto with mem.
+ destruct H0 as [v' LOAD].
+ destruct (load_store_classification chunk b ofs chunk' b' ofs').
+ subst b' ofs'. apply load_store_similar; auto.
+ apply load_store_other; intuition.
+ subst b'. rewrite LOAD. decEq.
+ eapply load_store_overlap; eauto.
+ subst b' ofs'. rewrite LOAD. decEq.
+ eapply load_store_mismatch; eauto.
Qed.
-Theorem low_bound_free:
- forall (m: mem) (b bf: block),
- b <> bf ->
- low_bound (free m bf) b = low_bound m b.
+End STORE.
+
+Hint Resolve store_valid_block_1 store_valid_block_2: mem.
+Hint Resolve store_valid_access_1 store_valid_access_2
+ store_valid_access_3: mem.
+
+(** ** Properties related to [alloc]. *)
+
+Section ALLOC.
+
+Variable m1: mem.
+Variables lo hi: Z.
+Variable m2: mem.
+Variable b: block.
+Hypothesis ALLOC: alloc m1 lo hi = (m2, b).
+
+Lemma nextblock_alloc:
+ nextblock m2 = Zsucc (nextblock m1).
Proof.
- intros. unfold free, low_bound; simpl.
- rewrite update_o; auto.
+ injection ALLOC; intros. rewrite <- H0; auto.
Qed.
-Theorem high_bound_free:
- forall (m: mem) (b bf: block),
- b <> bf ->
- high_bound (free m bf) b = high_bound m b.
+Lemma alloc_result:
+ b = nextblock m1.
Proof.
- intros. unfold free, high_bound; simpl.
- rewrite update_o; auto.
+ injection ALLOC; auto.
Qed.
-Hint Resolve load_free low_bound_free high_bound_free.
-(** ** Properties related to [store] *)
+Lemma valid_block_alloc:
+ forall b', valid_block m1 b' -> valid_block m2 b'.
+Proof.
+ unfold valid_block; intros. rewrite nextblock_alloc. omega.
+Qed.
-Lemma store_is_in_bounds:
- forall chunk m1 b ofs v m2,
- store chunk m1 b ofs v = Some m2 ->
- low_bound m1 b <= ofs /\ ofs + size_chunk chunk <= high_bound m1 b.
+Lemma fresh_block_alloc:
+ ~(valid_block m1 b).
Proof.
- intros. generalize (store_inv _ _ _ _ _ _ H).
- intros [A [B [C [P D]]]].
- unfold low_bound, high_bound. tauto.
+ unfold valid_block. rewrite alloc_result. omega.
Qed.
-Lemma load_store_contents_same:
- forall (sz: memory_size) (c: contentmap) (ofs: Z) (v: val),
- load_contents sz (store_contents sz c ofs v) ofs = v.
+Lemma valid_new_block:
+ valid_block m2 b.
Proof.
- intros until v.
- unfold load_contents, store_contents in |- *; case sz;
- rewrite getN_setN_same; reflexivity.
+ unfold valid_block. rewrite alloc_result. rewrite nextblock_alloc. omega.
Qed.
-
-Theorem load_store_same:
- forall (chunk: memory_chunk) (m1 m2: mem) (b: block) (ofs: Z) (v: val),
- store chunk m1 b ofs v = Some m2 ->
- load chunk m2 b ofs = Some (Val.load_result chunk v).
+
+Hint Resolve valid_block_alloc fresh_block_alloc valid_new_block: mem.
+
+Lemma valid_block_alloc_inv:
+ forall b', valid_block m2 b' -> b' = b \/ valid_block m1 b'.
Proof.
- intros.
- generalize (store_inv _ _ _ _ _ _ H).
- intros (A, (B, (C, (D, (P, E))))).
- unfold load. rewrite D.
- rewrite zlt_true; auto. rewrite E.
- repeat (rewrite update_s). simpl.
- rewrite in_bounds_exten. rewrite in_bounds_holds; auto.
- rewrite load_store_contents_same; auto.
-Qed.
-
-Lemma load_store_contents_other:
- forall (sz1 sz2: memory_size) (c: contentmap)
- (ofs1 ofs2: Z) (v: val),
- ofs2 + size_mem sz2 <= ofs1 \/ ofs1 + size_mem sz1 <= ofs2 ->
- load_contents sz2 (store_contents sz1 c ofs1 v) ofs2 =
- load_contents sz2 c ofs2.
-Proof.
- intros until v.
- unfold size_mem, store_contents, load_contents;
- case sz1; case sz2; intros;
- (rewrite getN_setN_other;
- [reflexivity | simpl Z_of_nat; omega]).
+ unfold valid_block; intros.
+ rewrite nextblock_alloc in H. rewrite alloc_result.
+ unfold block; omega.
Qed.
-Theorem load_store_other:
- forall (chunk1 chunk2: memory_chunk) (m1 m2: mem)
- (b1 b2: block) (ofs1 ofs2: Z) (v: val),
- store chunk1 m1 b1 ofs1 v = Some m2 ->
- b1 <> b2
- \/ ofs2 + size_chunk chunk2 <= ofs1
- \/ ofs1 + size_chunk chunk1 <= ofs2 ->
- load chunk2 m2 b2 ofs2 = load chunk2 m1 b2 ofs2.
+Lemma low_bound_alloc:
+ forall b', low_bound m2 b' = if zeq b' b then lo else low_bound m1 b'.
Proof.
- intros.
- generalize (store_inv _ _ _ _ _ _ H).
- intros (A, (B, (C, (D, (P, E))))).
- unfold load. rewrite D.
- case (zlt b2 (nextblock m1)); intro.
- rewrite E; unfold update; case (zeq b2 b1); intro; simpl.
- subst b2. rewrite in_bounds_exten.
- rewrite load_store_contents_other. auto.
- tauto.
- reflexivity.
- reflexivity.
-Qed.
-
-Ltac LSCO :=
- match goal with
- | |- (match getN ?sz2 ?ofs2 (setN ?sz1 ?ofs1 ?v ?c) with
- | Undef => _
- | Datum8 _ => _
- | Datum16 _ => _
- | Datum32 _ => _
- | Datum64 _ => _
- | Cont => _
- end = _) =>
- elim (getN_setN_overlap sz1 sz2 ofs1 ofs2 v c);
- [ let H := fresh in (intro H; rewrite H; reflexivity)
- | let H := fresh in (intro H; rewrite H; reflexivity)
- | assumption
- | simpl Z_of_nat; omega
- | simpl Z_of_nat; omega
- | discriminate ]
- end.
+ intros. injection ALLOC; intros. rewrite <- H0; unfold low_bound; simpl.
+ unfold update. rewrite H. destruct (zeq b' b); auto.
+Qed.
-Lemma load_store_contents_overlap:
- forall (sz1 sz2: memory_size) (c: contentmap)
- (ofs1 ofs2: Z) (v: val),
- ofs1 <> ofs2 ->
- ofs2 + size_mem sz2 > ofs1 -> ofs1 + size_mem sz1 > ofs2 ->
- load_contents sz2 (store_contents sz1 c ofs1 v) ofs2 = Vundef.
+Lemma low_bound_alloc_same:
+ low_bound m2 b = lo.
Proof.
- intros.
- destruct sz1; destruct sz2; simpl in H0; simpl in H1; simpl; LSCO.
-Qed.
-
-Ltac LSCM :=
- match goal with
- | H:(?x <> ?x) |- _ =>
- elim H; reflexivity
- | |- (match getN ?sz2 ?ofs (setN ?sz1 ?ofs ?v ?c) with
- | Undef => _
- | Datum8 _ => _
- | Datum16 _ => _
- | Datum32 _ => _
- | Datum64 _ => _
- | Cont => _
- end = _) =>
- elim (getN_setN_mismatch sz1 sz2 ofs v c);
- [ let H := fresh in (intro H; rewrite H; reflexivity)
- | let H := fresh in (intro H; rewrite H; reflexivity) ]
- end.
+ rewrite low_bound_alloc. apply zeq_true.
+Qed.
-Lemma load_store_contents_mismatch:
- forall (sz1 sz2: memory_size) (c: contentmap)
- (ofs: Z) (v: val),
- sz1 <> sz2 ->
- load_contents sz2 (store_contents sz1 c ofs v) ofs = Vundef.
+Lemma low_bound_alloc_other:
+ forall b', valid_block m1 b' -> low_bound m2 b' = low_bound m1 b'.
Proof.
- intros.
- destruct sz1; destruct sz2; simpl; LSCM.
-Qed.
+ intros; rewrite low_bound_alloc.
+ apply zeq_false. eauto with mem.
+Qed.
-Theorem low_bound_store:
- forall (chunk: memory_chunk) (m1 m2: mem) (b b': block) (ofs: Z) (v: val),
- store chunk m1 b ofs v = Some m2 ->
- low_bound m2 b' = low_bound m1 b'.
+Lemma high_bound_alloc:
+ forall b', high_bound m2 b' = if zeq b' b then hi else high_bound m1 b'.
Proof.
- intros.
- generalize (store_inv _ _ _ _ _ _ H).
- intros (A, (B, (C, (D, (P, E))))).
- unfold low_bound. rewrite E; unfold update.
- case (zeq b' b); intro.
- subst b'. reflexivity.
- reflexivity.
+ intros. injection ALLOC; intros. rewrite <- H0; unfold high_bound; simpl.
+ unfold update. rewrite H. destruct (zeq b' b); auto.
Qed.
-Theorem high_bound_store:
- forall (chunk: memory_chunk) (m1 m2: mem) (b b': block) (ofs: Z) (v: val),
- store chunk m1 b ofs v = Some m2 ->
- high_bound m2 b' = high_bound m1 b'.
+Lemma high_bound_alloc_same:
+ high_bound m2 b = hi.
Proof.
- intros.
- generalize (store_inv _ _ _ _ _ _ H).
- intros (A, (B, (C, (D, (P, E))))).
- unfold high_bound. rewrite E; unfold update.
- case (zeq b' b); intro.
- subst b'. reflexivity.
- reflexivity.
+ rewrite high_bound_alloc. apply zeq_true.
Qed.
-Hint Resolve high_bound_store low_bound_store load_store_contents_mismatch
- load_store_contents_overlap load_store_other store_is_in_bounds
- load_store_contents_same load_store_same load_store_contents_other.
+Lemma high_bound_alloc_other:
+ forall b', valid_block m1 b' -> high_bound m2 b' = high_bound m1 b'.
+Proof.
+ intros; rewrite high_bound_alloc.
+ apply zeq_false. eauto with mem.
+Qed.
-(** * Agreement between memory blocks. *)
+Lemma valid_access_alloc_other:
+ forall chunk b' ofs,
+ valid_access m1 chunk b' ofs ->
+ valid_access m2 chunk b' ofs.
+Proof.
+ intros. inv H. constructor. auto with mem.
+ rewrite low_bound_alloc_other; auto.
+ rewrite high_bound_alloc_other; auto.
+Qed.
-(** Two memory blocks [c1] and [c2] agree on a range [lo] to [hi]
- if they associate the same contents to byte offsets in the range
- [lo] (included) to [hi] (excluded). *)
+Lemma valid_access_alloc_same:
+ forall chunk ofs,
+ lo <= ofs -> ofs + size_chunk chunk <= hi ->
+ valid_access m2 chunk b ofs.
+Proof.
+ intros. constructor. auto with mem.
+ rewrite low_bound_alloc_same; auto.
+ rewrite high_bound_alloc_same; auto.
+Qed.
+
+Hint Resolve valid_access_alloc_other valid_access_alloc_same: mem.
+
+Lemma valid_access_alloc_inv:
+ forall chunk b' ofs,
+ valid_access m2 chunk b' ofs ->
+ valid_access m1 chunk b' ofs \/
+ (b' = b /\ lo <= ofs /\ ofs + size_chunk chunk <= hi).
+Proof.
+ intros. inv H.
+ elim (valid_block_alloc_inv _ H0); intro.
+ subst b'. rewrite low_bound_alloc_same in H1.
+ rewrite high_bound_alloc_same in H2.
+ right. tauto.
+ left. constructor. auto.
+ rewrite low_bound_alloc_other in H1; auto.
+ rewrite high_bound_alloc_other in H2; auto.
+Qed.
+
+Theorem load_alloc_unchanged:
+ forall chunk b' ofs,
+ valid_block m1 b' ->
+ load chunk m2 b' ofs = load chunk m1 b' ofs.
+Proof.
+ intros. unfold load.
+ destruct (in_bounds m2 chunk b' ofs).
+ elim (valid_access_alloc_inv _ _ _ v). intro.
+ rewrite in_bounds_true; auto.
+ injection ALLOC; intros. rewrite <- H2; simpl.
+ rewrite update_o. auto. rewrite H1. apply sym_not_equal. eauto with mem.
+ intros [A [B C]]. subst b'. elimtype False. eauto with mem.
+ destruct (in_bounds m1 chunk b' ofs).
+ elim n; eauto with mem.
+ auto.
+Qed.
-Definition contentmap_agree (lo hi: Z) (c1 c2: contentmap) :=
- forall (ofs: Z),
- lo <= ofs < hi -> c1 ofs = c2 ofs.
+Theorem load_alloc_other:
+ forall chunk b' ofs v,
+ load chunk m1 b' ofs = Some v ->
+ load chunk m2 b' ofs = Some v.
+Proof.
+ intros. rewrite <- H. apply load_alloc_unchanged. eauto with mem.
+Qed.
-Definition block_contents_agree (lo hi: Z) (c1 c2: block_contents) :=
- contentmap_agree lo hi c1.(contents) c2.(contents).
+Theorem load_alloc_same:
+ forall chunk ofs v,
+ load chunk m2 b ofs = Some v ->
+ v = Vundef.
+Proof.
+ intros. destruct (load_inv _ _ _ _ _ H). rewrite H1.
+ injection ALLOC; intros. rewrite <- H3; simpl.
+ rewrite <- H2. rewrite update_s.
+ simpl. rewrite getN_init. destruct chunk; auto.
+Qed.
+
+Theorem load_alloc_same':
+ forall chunk ofs,
+ lo <= ofs -> ofs + size_chunk chunk <= hi ->
+ load chunk m2 b ofs = Some Vundef.
+Proof.
+ intros. assert (exists v, load chunk m2 b ofs = Some v).
+ apply valid_access_load. constructor; eauto with mem.
+ rewrite low_bound_alloc_same. auto.
+ rewrite high_bound_alloc_same. auto.
+ destruct H1 as [v LOAD]. rewrite LOAD. decEq.
+ eapply load_alloc_same; eauto.
+Qed.
+
+End ALLOC.
+
+Hint Resolve valid_block_alloc fresh_block_alloc valid_new_block: mem.
+Hint Resolve valid_access_alloc_other valid_access_alloc_same: mem.
+Hint Resolve load_alloc_unchanged: mem.
+
+(** ** Properties related to [free]. *)
-Definition block_agree (b: block) (lo hi: Z) (m1 m2: mem) :=
- block_contents_agree lo hi
- (m1.(blocks) b) (m2.(blocks) b).
+Section FREE.
-Theorem block_agree_refl:
- forall (m: mem) (b: block) (lo hi: Z),
- block_agree b lo hi m m.
+Variable m: mem.
+Variable bf: block.
+
+Lemma valid_block_free_1:
+ forall b, valid_block m b -> valid_block (free m bf) b.
Proof.
- intros. hnf. auto.
+ unfold valid_block, free; intros; simpl; auto.
Qed.
-Theorem block_agree_sym:
- forall (m1 m2: mem) (b: block) (lo hi: Z),
- block_agree b lo hi m1 m2 ->
- block_agree b lo hi m2 m1.
+Lemma valid_block_free_2:
+ forall b, valid_block (free m bf) b -> valid_block m b.
Proof.
- intros. hnf. intros. symmetry. apply H. auto.
+ unfold valid_block, free; intros; simpl in *; auto.
Qed.
-Theorem block_agree_trans:
- forall (m1 m2 m3: mem) (b: block) (lo hi: Z),
- block_agree b lo hi m1 m2 ->
- block_agree b lo hi m2 m3 ->
- block_agree b lo hi m1 m3.
+Hint Resolve valid_block_free_1 valid_block_free_2: mem.
+
+Lemma low_bound_free:
+ forall b, b <> bf -> low_bound (free m bf) b = low_bound m b.
Proof.
- intros. hnf. intros.
- transitivity (contents (blocks m2 b) ofs).
- apply H; auto. apply H0; auto.
+ intros. unfold low_bound, free; simpl.
+ rewrite update_o; auto.
Qed.
-Lemma check_cont_agree:
- forall (c1 c2: contentmap) (lo hi: Z),
- contentmap_agree lo hi c1 c2 ->
- forall (n: nat) (ofs: Z),
- lo <= ofs -> ofs + Z_of_nat n <= hi ->
- check_cont n ofs c2 = check_cont n ofs c1.
+Lemma high_bound_free:
+ forall b, b <> bf -> high_bound (free m bf) b = high_bound m b.
Proof.
- induction n; intros; simpl.
- auto.
- rewrite inj_S in H1.
- rewrite H. case (c2 ofs); intros; auto.
- apply IHn; omega.
- omega.
+ intros. unfold high_bound, free; simpl.
+ rewrite update_o; auto.
Qed.
-Lemma getN_agree:
- forall (c1 c2: contentmap) (lo hi: Z),
- contentmap_agree lo hi c1 c2 ->
- forall (n: nat) (ofs: Z),
- lo <= ofs -> ofs + Z_of_nat n < hi ->
- getN n ofs c2 = getN n ofs c1.
+Lemma low_bound_free_same:
+ forall m b, low_bound (free m b) b = 0.
Proof.
- intros. unfold getN.
- rewrite (check_cont_agree c1 c2 lo hi H n (ofs + 1)).
- case (check_cont n (ofs + 1) c1).
- symmetry. apply H. omega. auto.
- omega. omega.
+ intros. unfold low_bound; simpl. rewrite update_s. simpl; omega.
Qed.
-Lemma load_contentmap_agree:
- forall (sz: memory_size) (c1 c2: contentmap) (lo hi ofs: Z),
- contentmap_agree lo hi c1 c2 ->
- lo <= ofs -> ofs + size_mem sz <= hi ->
- load_contents sz c2 ofs = load_contents sz c1 ofs.
+Lemma high_bound_free_same:
+ forall m b, high_bound (free m b) b = 0.
Proof.
- intros sz c1 c2 lo hi ofs EX LO.
- unfold load_contents, size_mem; case sz; intro HI;
- rewrite (getN_agree c1 c2 lo hi EX); auto; simpl Z_of_nat; omega.
+ intros. unfold high_bound; simpl. rewrite update_s. simpl; omega.
Qed.
-Lemma set_cont_agree:
- forall (lo hi: Z) (n: nat) (c1 c2: contentmap) (ofs: Z),
- contentmap_agree lo hi c1 c2 ->
- contentmap_agree lo hi (set_cont n ofs c1) (set_cont n ofs c2).
+Lemma valid_access_free_1:
+ forall chunk b ofs,
+ valid_access m chunk b ofs -> b <> bf ->
+ valid_access (free m bf) chunk b ofs.
Proof.
- induction n; simpl; intros.
- auto.
- red. intros p B.
- case (zeq p ofs); intro.
- subst p. repeat (rewrite update_s). reflexivity.
- repeat (rewrite update_o). apply IHn. assumption.
- assumption. auto. auto.
+ intros. inv H. constructor. auto with mem.
+ rewrite low_bound_free; auto. rewrite high_bound_free; auto.
Qed.
-Lemma setN_agree:
- forall (lo hi: Z) (n: nat) (c1 c2: contentmap) (ofs: Z) (v: content),
- contentmap_agree lo hi c1 c2 ->
- contentmap_agree lo hi (setN n ofs v c1) (setN n ofs v c2).
+Lemma valid_access_free_2:
+ forall chunk ofs, ~(valid_access (free m bf) chunk bf ofs).
Proof.
- intros. unfold setN. red; intros p B.
- case (zeq p ofs); intro.
- subst p. repeat (rewrite update_s). reflexivity.
- repeat (rewrite update_o; auto).
- exact (set_cont_agree lo hi n c1 c2 (ofs + 1) H p B).
+ intros; red; intros. inv H.
+ unfold free, low_bound in H1; simpl in H1. rewrite update_s in H1. simpl in H1.
+ unfold free, high_bound in H2; simpl in H2. rewrite update_s in H2. simpl in H2.
+ generalize (size_chunk_pos chunk). omega.
Qed.
-Lemma store_contentmap_agree:
- forall (sz: memory_size) (c1 c2: contentmap) (lo hi ofs: Z) (v: val),
- contentmap_agree lo hi c1 c2 ->
- contentmap_agree lo hi
- (store_contents sz c1 ofs v) (store_contents sz c2 ofs v).
+Hint Resolve valid_access_free_1 valid_access_free_2: mem.
+
+Lemma valid_access_free_inv:
+ forall chunk b ofs,
+ valid_access (free m bf) chunk b ofs ->
+ valid_access m chunk b ofs /\ b <> bf.
Proof.
- intros. unfold store_contents; case sz; apply setN_agree; auto.
+ intros. destruct (eq_block b bf). subst b.
+ elim (valid_access_free_2 _ _ H).
+ inv H. rewrite low_bound_free in H1; auto.
+ rewrite high_bound_free in H2; auto.
+ split; auto. constructor; auto with mem.
Qed.
-Lemma set_cont_outside_agree:
- forall (lo hi: Z) (n: nat) (c1 c2: contentmap) (ofs: Z),
- contentmap_agree lo hi c1 c2 ->
- ofs + Z_of_nat n <= lo \/ hi <= ofs ->
- contentmap_agree lo hi c1 (set_cont n ofs c2).
+Theorem load_free:
+ forall chunk b ofs,
+ b <> bf ->
+ load chunk (free m bf) b ofs = load chunk m b ofs.
Proof.
- induction n; intros; simpl.
- auto.
- red; intros p R. rewrite inj_S in H0.
- unfold update. case (zeq p ofs); intro.
- subst p. omegaContradiction.
- apply IHn. auto. omega. auto.
+ intros. unfold load.
+ destruct (in_bounds m chunk b ofs).
+ rewrite in_bounds_true; auto with mem.
+ unfold free; simpl. rewrite update_o; auto.
+ destruct (in_bounds (free m bf) chunk b ofs); auto.
+ elim n. elim (valid_access_free_inv _ _ _ v); auto.
+Qed.
+
+End FREE.
+
+(** ** Properties related to [free_list] *)
+
+Lemma valid_block_free_list_1:
+ forall bl m b, valid_block m b -> valid_block (free_list m bl) b.
+Proof.
+ induction bl; simpl; intros. auto.
+ apply valid_block_free_1; auto.
Qed.
-Lemma setN_outside_agree:
- forall (lo hi: Z) (n: nat) (c1 c2: contentmap) (ofs: Z) (v: content),
- contentmap_agree lo hi c1 c2 ->
- ofs + Z_of_nat n < lo \/ hi <= ofs ->
- contentmap_agree lo hi c1 (setN n ofs v c2).
+Lemma valid_block_free_list_2:
+ forall bl m b, valid_block (free_list m bl) b -> valid_block m b.
Proof.
- intros. unfold setN. red; intros p R.
- unfold update. case (zeq p ofs); intro.
- omegaContradiction.
- apply (set_cont_outside_agree lo hi n c1 c2 (ofs + 1) H).
- omega. auto.
+ induction bl; simpl; intros. auto.
+ apply IHbl. apply valid_block_free_2 with a; auto.
Qed.
-Lemma store_contentmap_outside_agree:
- forall (sz: memory_size) (c1 c2: contentmap) (lo hi ofs: Z) (v: val),
- contentmap_agree lo hi c1 c2 ->
- ofs + size_mem sz <= lo \/ hi <= ofs ->
- contentmap_agree lo hi c1 (store_contents sz c2 ofs v).
+Lemma valid_access_free_list:
+ forall chunk b ofs m bl,
+ valid_access m chunk b ofs -> ~In b bl ->
+ valid_access (free_list m bl) chunk b ofs.
Proof.
- intros until v.
- unfold store_contents; case sz; simpl; intros;
- apply setN_outside_agree; auto; simpl Z_of_nat; omega.
+ induction bl; simpl; intros. auto.
+ apply valid_access_free_1. apply IHbl. auto. intuition. intuition congruence.
Qed.
-Theorem load_agree:
- forall (chunk: memory_chunk) (m1 m2: mem)
- (b: block) (lo hi: Z) (ofs: Z) (v1 v2: val),
- block_agree b lo hi m1 m2 ->
- lo <= ofs -> ofs + size_chunk chunk <= hi ->
- load chunk m1 b ofs = Some v1 ->
- load chunk m2 b ofs = Some v2 ->
- v1 = v2.
+Lemma valid_access_free_list_inv:
+ forall chunk b ofs m bl,
+ valid_access (free_list m bl) chunk b ofs ->
+ ~In b bl /\ valid_access m chunk b ofs.
+Proof.
+ induction bl; simpl; intros.
+ tauto.
+ elim (valid_access_free_inv _ _ _ _ _ H); intros.
+ elim (IHbl H0); intros.
+ intuition congruence.
+Qed.
+
+(** ** Properties related to pointer validity *)
+
+Lemma valid_pointer_valid_access:
+ forall m b ofs,
+ valid_pointer m b ofs = true <-> valid_access m Mint8unsigned b ofs.
+Proof.
+ unfold valid_pointer; intros; split; intros.
+ destruct (andb_prop _ _ H). destruct (andb_prop _ _ H0).
+ constructor. red. eapply proj_sumbool_true; eauto.
+ eapply proj_sumbool_true; eauto.
+ change (size_chunk Mint8unsigned) with 1.
+ generalize (proj_sumbool_true _ H1). omega.
+ inv H. unfold proj_sumbool.
+ rewrite zlt_true; auto. rewrite zle_true; auto.
+ change (size_chunk Mint8unsigned) with 1 in H2.
+ rewrite zlt_true. auto. omega.
+Qed.
+
+Theorem valid_pointer_alloc:
+ forall (m1 m2: mem) (lo hi: Z) (b b': block) (ofs: Z),
+ alloc m1 lo hi = (m2, b') ->
+ valid_pointer m1 b ofs = true ->
+ valid_pointer m2 b ofs = true.
+Proof.
+ intros. rewrite valid_pointer_valid_access in H0.
+ rewrite valid_pointer_valid_access.
+ eauto with mem.
+Qed.
+
+Theorem valid_pointer_store:
+ forall (chunk: memory_chunk) (m1 m2: mem) (b b': block) (ofs ofs': Z) (v: val),
+ store chunk m1 b' ofs' v = Some m2 ->
+ valid_pointer m1 b ofs = true -> valid_pointer m2 b ofs = true.
+Proof.
+ intros. rewrite valid_pointer_valid_access in H0.
+ rewrite valid_pointer_valid_access.
+ eauto with mem.
+Qed.
+
+(** * Generic injections between memory states. *)
+
+Section GENERIC_INJECT.
+
+Definition meminj : Set := block -> option (block * Z).
+
+Variable val_inj: meminj -> val -> val -> Prop.
+
+(*
+Hypothesis val_inj_ptr:
+ forall mi b1 ofs1 b2 ofs2,
+ val_inj mi (Vptr b1 ofs1) (Vptr b2 ofs2) <->
+ exists delta, mi b1 = Some(b2, delta) /\ ofs2 = Int.repr (Int.signed ofs1 + delta).
+*)
+
+Hypothesis val_inj_undef:
+ forall mi, val_inj mi Vundef Vundef.
+
+Definition mem_inj (mi: meminj) (m1 m2: mem) :=
+ forall chunk b1 ofs v1 b2 delta,
+ mi b1 = Some(b2, delta) ->
+ load chunk m1 b1 ofs = Some v1 ->
+ exists v2, load chunk m2 b2 (ofs + delta) = Some v2 /\ val_inj mi v1 v2.
+
+Lemma valid_access_inj:
+ forall mi m1 m2 chunk b1 ofs b2 delta,
+ mi b1 = Some(b2, delta) ->
+ mem_inj mi m1 m2 ->
+ valid_access m1 chunk b1 ofs ->
+ valid_access m2 chunk b2 (ofs + delta).
Proof.
intros.
- generalize (load_inv _ _ _ _ _ H2). intros [K [L [M N]]].
- generalize (load_inv _ _ _ _ _ H3). intros [P [Q [R S]]].
- subst v1; subst v2. symmetry.
- decEq. eapply load_contentmap_agree.
- apply H. auto. auto.
-Qed.
-
-Theorem store_agree:
- forall (chunk: memory_chunk) (m1 m2 m1' m2': mem)
- (b: block) (lo hi: Z)
- (b': block) (ofs: Z) (v: val),
- block_agree b lo hi m1 m2 ->
- store chunk m1 b' ofs v = Some m1' ->
- store chunk m2 b' ofs v = Some m2' ->
- block_agree b lo hi m1' m2'.
+ assert (exists v1, load chunk m1 b1 ofs = Some v1) by eauto with mem.
+ destruct H2 as [v1 LOAD1].
+ destruct (H0 _ _ _ _ _ _ H LOAD1) as [v2 [LOAD2 VCP]].
+ eauto with mem.
+Qed.
+
+Hint Resolve valid_access_inj: mem.
+
+Lemma store_unmapped_inj:
+ forall mi m1 m2 b ofs v chunk m1',
+ mem_inj mi m1 m2 ->
+ mi b = None ->
+ store chunk m1 b ofs v = Some m1' ->
+ mem_inj mi m1' m2.
+Proof.
+ intros; red; intros.
+ assert (load chunk0 m1 b1 ofs0 = Some v1).
+ rewrite <- H3; symmetry. eapply load_store_other; eauto.
+ left. congruence.
+ eapply H; eauto.
+Qed.
+
+Lemma store_outside_inj:
+ forall mi m1 m2 chunk b ofs v m2',
+ mem_inj mi m1 m2 ->
+ (forall b' delta,
+ mi b' = Some(b, delta) ->
+ high_bound m1 b' + delta <= ofs
+ \/ ofs + size_chunk chunk <= low_bound m1 b' + delta) ->
+ store chunk m2 b ofs v = Some m2' ->
+ mem_inj mi m1 m2'.
+Proof.
+ intros; red; intros.
+ exploit H; eauto. intros [v2 [LOAD2 VINJ]].
+ exists v2; split; auto.
+ rewrite <- LOAD2. eapply load_store_other; eauto.
+ destruct (eq_block b2 b). subst b2.
+ right. generalize (H0 _ _ H2); intro.
+ assert (valid_access m1 chunk0 b1 ofs0) by eauto with mem.
+ inv H5. omega. auto.
+Qed.
+
+Definition meminj_no_overlap (mi: meminj) (m: mem) : Prop :=
+ forall b1 b1' delta1 b2 b2' delta2,
+ b1 <> b2 ->
+ mi b1 = Some (b1', delta1) ->
+ mi b2 = Some (b2', delta2) ->
+ b1' <> b2'
+ \/ low_bound m b1 >= high_bound m b1
+ \/ low_bound m b2 >= high_bound m b2
+ \/ high_bound m b1 + delta1 <= low_bound m b2 + delta2
+ \/ high_bound m b2 + delta2 <= low_bound m b1 + delta1.
+
+Lemma store_mapped_inj:
+ forall mi m1 m2 b1 ofs b2 delta v1 v2 chunk m1',
+ mem_inj mi m1 m2 ->
+ meminj_no_overlap mi m1 ->
+ mi b1 = Some(b2, delta) ->
+ store chunk m1 b1 ofs v1 = Some m1' ->
+ (forall chunk', size_chunk chunk' = size_chunk chunk ->
+ val_inj mi (Val.load_result chunk' v1) (Val.load_result chunk' v2)) ->
+ exists m2',
+ store chunk m2 b2 (ofs + delta) v2 = Some m2' /\ mem_inj mi m1' m2'.
Proof.
- intros.
- generalize (store_inv _ _ _ _ _ _ H0).
- intros [I [J [K [L [x M]]]]].
- generalize (store_inv _ _ _ _ _ _ H1).
- intros [P [Q [R [S [y T]]]]].
- red. red.
- rewrite M; rewrite T; unfold update.
- case (zeq b b'); intro; simpl.
- subst b'. apply store_contentmap_agree. assumption.
- apply H.
-Qed.
-
-Theorem store_outside_agree:
- forall (chunk: memory_chunk) (m1 m2 m2': mem)
- (b: block) (lo hi: Z)
- (b': block) (ofs: Z) (v: val),
- block_agree b lo hi m1 m2 ->
- b <> b' \/ ofs + size_chunk chunk <= lo \/ hi <= ofs ->
- store chunk m2 b' ofs v = Some m2' ->
- block_agree b lo hi m1 m2'.
+ intros.
+ assert (exists m2', store chunk m2 b2 (ofs + delta) v2 = Some m2') by eauto with mem.
+ destruct H4 as [m2' STORE2].
+ exists m2'; split. auto.
+ red. intros chunk' b1' ofs' v b2' delta' CP LOAD1.
+ assert (valid_access m1 chunk' b1' ofs') by eauto with mem.
+ generalize (load_store_characterization _ _ _ _ _ _ H2 _ _ _ H4).
+ destruct (load_store_classification chunk b1 ofs chunk' b1' ofs');
+ intro.
+ (* similar *)
+ subst b1' ofs'.
+ rewrite CP in H1. inv H1.
+ rewrite LOAD1 in H5. inv H5.
+ exists (Val.load_result chunk' v2). split.
+ eapply load_store_similar; eauto.
+ auto.
+ (* disjoint *)
+ rewrite LOAD1 in H5.
+ destruct (H _ _ _ _ _ _ CP (sym_equal H5)) as [v2' [LOAD2 VCP]].
+ exists v2'. split; auto.
+ rewrite <- LOAD2. eapply load_store_other; eauto.
+ destruct (eq_block b1 b1'). subst b1'.
+ rewrite CP in H1; inv H1.
+ right. elim o; [congruence | omega].
+ assert (valid_access m1 chunk b1 ofs) by eauto with mem.
+ generalize (H0 _ _ _ _ _ _ n H1 CP). intros [A | [A | [A | A]]].
+ auto.
+ inv H6. generalize (size_chunk_pos chunk). intro. omegaContradiction.
+ inv H4. generalize (size_chunk_pos chunk'). intro. omegaContradiction.
+ right. inv H4. inv H6. omega.
+ (* overlapping *)
+ subst b1'. rewrite CP in H1; inv H1.
+ assert (exists v2', load chunk' m2' b2 (ofs' + delta) = Some v2') by eauto with mem.
+ destruct H1 as [v2' LOAD2'].
+ assert (v2' = Vundef). eapply load_store_overlap; eauto.
+ omega. omega. omega.
+ exists v2'; split. auto.
+ replace v with Vundef by congruence. subst v2'. apply val_inj_undef.
+ (* mismatch *)
+ subst b1' ofs'. rewrite CP in H1; inv H1.
+ assert (exists v2', load chunk' m2' b2 (ofs + delta) = Some v2') by eauto with mem.
+ destruct H1 as [v2' LOAD2'].
+ assert (v2' = Vundef). eapply load_store_mismatch; eauto.
+ exists v2'; split. auto.
+ replace v with Vundef by congruence. subst v2'. apply val_inj_undef.
+Qed.
+
+Lemma alloc_parallel_inj:
+ forall mi m1 m2 lo1 hi1 m1' b1 lo2 hi2 m2' b2 delta,
+ mem_inj mi m1 m2 ->
+ alloc m1 lo1 hi1 = (m1', b1) ->
+ alloc m2 lo2 hi2 = (m2', b2) ->
+ mi b1 = Some(b2, delta) ->
+ lo2 <= lo1 + delta -> hi1 + delta <= hi2 ->
+ mem_inj mi m1' m2'.
+Proof.
+ intros; red; intros.
+ exploit (valid_access_alloc_inv m1); eauto with mem.
+ intros [A | [A [B C]]].
+ assert (load chunk m1 b0 ofs = Some v1).
+ rewrite <- H6. symmetry. eapply load_alloc_unchanged; eauto with mem.
+ exploit H; eauto. intros [v2 [LOAD2 VINJ]].
+ exists v2; split.
+ rewrite <- LOAD2. eapply load_alloc_unchanged; eauto with mem.
+ auto.
+ subst b0. rewrite H2 in H5. inversion H5. subst b3 delta0.
+ assert (v1 = Vundef). eapply load_alloc_same with (m1 := m1); eauto.
+ subst v1.
+ assert (exists v2, load chunk m2' b2 (ofs + delta) = Some v2).
+ apply valid_access_load.
+ eapply valid_access_alloc_same; eauto. omega. omega.
+ destruct H7 as [v2 LOAD2].
+ assert (v2 = Vundef). eapply load_alloc_same with (m1 := m2); eauto.
+ subst v2.
+ exists Vundef; split. auto. apply val_inj_undef.
+Qed.
+
+Lemma alloc_right_inj:
+ forall mi m1 m2 lo hi b2 m2',
+ mem_inj mi m1 m2 ->
+ alloc m2 lo hi = (m2', b2) ->
+ mem_inj mi m1 m2'.
Proof.
- intros.
- generalize (store_inv _ _ _ _ _ _ H1).
- intros [I [J [K [L [x M]]]]].
- red. red. rewrite M; unfold update;
- case (zeq b b'); intro; simpl.
- subst b'. apply store_contentmap_outside_agree.
- assumption.
- elim H0; intro. tauto. exact H2.
- apply H.
+ intros; red; intros.
+ exploit H; eauto. intros [v2 [LOAD2 VINJ]].
+ exists v2; split; auto.
+ assert (valid_block m2 b0).
+ apply valid_access_valid_block with chunk (ofs + delta).
+ eauto with mem.
+ rewrite <- LOAD2. eapply load_alloc_unchanged; eauto.
+Qed.
+
+Hypothesis val_inj_undef_any:
+ forall mi v, val_inj mi Vundef v.
+
+Lemma alloc_left_unmapped_inj:
+ forall mi m1 m2 lo hi b1 m1',
+ mem_inj mi m1 m2 ->
+ alloc m1 lo hi = (m1', b1) ->
+ mi b1 = None ->
+ mem_inj mi m1' m2.
+Proof.
+ intros; red; intros.
+ exploit (valid_access_alloc_inv m1); eauto with mem.
+ intros [A | [A [B C]]].
+ eapply H; eauto.
+ rewrite <- H3. symmetry. eapply load_alloc_unchanged; eauto with mem.
+ subst b0. congruence.
+Qed.
+
+Lemma alloc_left_mapped_inj:
+ forall mi m1 m2 lo hi b1 m1' b2 delta,
+ mem_inj mi m1 m2 ->
+ alloc m1 lo hi = (m1', b1) ->
+ mi b1 = Some(b2, delta) ->
+ valid_block m2 b2 ->
+ low_bound m2 b2 <= lo + delta -> hi + delta <= high_bound m2 b2 ->
+ mem_inj mi m1' m2.
+Proof.
+ intros; red; intros.
+ exploit (valid_access_alloc_inv m1); eauto with mem.
+ intros [A | [A [B C]]].
+ eapply H; eauto.
+ rewrite <- H6. symmetry. eapply load_alloc_unchanged; eauto with mem.
+ subst b0. rewrite H1 in H5. inversion H5. subst b3 delta0.
+ assert (v1 = Vundef). eapply load_alloc_same with (m1 := m1); eauto.
+ subst v1.
+ assert (exists v2, load chunk m2 b2 (ofs + delta) = Some v2).
+ apply valid_access_load. constructor. auto. omega. omega.
+ destruct H7 as [v2 LOAD2]. exists v2; split. auto.
+ apply val_inj_undef_any.
+Qed.
+
+Lemma free_parallel_inj:
+ forall mi m1 m2 b1 b2 delta,
+ mem_inj mi m1 m2 ->
+ mi b1 = Some(b2, delta) ->
+ (forall b delta', mi b = Some(b2, delta') -> b = b1) ->
+ mem_inj mi (free m1 b1) (free m2 b2).
+Proof.
+ intros; red; intros.
+ exploit valid_access_free_inv; eauto with mem. intros [A B].
+ assert (load chunk m1 b0 ofs = Some v1).
+ rewrite <- H3. symmetry. apply load_free. auto.
+ exploit H; eauto. intros [v2 [LOAD2 INJ]].
+ exists v2; split.
+ rewrite <- LOAD2. apply load_free.
+ red; intro; subst b3. elim B. eauto.
+ auto.
Qed.
-(** * Store extensions *)
+Lemma free_left_inj:
+ forall mi m1 m2 b1,
+ mem_inj mi m1 m2 ->
+ mem_inj mi (free m1 b1) m2.
+Proof.
+ intros; red; intros.
+ exploit valid_access_free_inv; eauto with mem. intros [A B].
+ eapply H; eauto with mem.
+ rewrite <- H1; symmetry; eapply load_free; eauto.
+Qed.
+
+Lemma free_list_left_inj:
+ forall mi bl m1 m2,
+ mem_inj mi m1 m2 ->
+ mem_inj mi (free_list m1 bl) m2.
+Proof.
+ induction bl; intros; simpl.
+ auto.
+ apply free_left_inj. auto.
+Qed.
+
+Lemma free_right_inj:
+ forall mi m1 m2 b2,
+ mem_inj mi m1 m2 ->
+ (forall b1 delta chunk ofs,
+ mi b1 = Some(b2, delta) -> ~(valid_access m1 chunk b1 ofs)) ->
+ mem_inj mi m1 (free m2 b2).
+Proof.
+ intros; red; intros.
+ assert (b0 <> b2).
+ red; intro; subst b0. elim (H0 b1 delta chunk ofs H1).
+ eauto with mem.
+ exploit H; eauto. intros [v2 [LOAD2 INJ]].
+ exists v2; split; auto.
+ rewrite <- LOAD2. apply load_free. auto.
+Qed.
+
+Lemma valid_pointer_inj:
+ forall mi m1 m2 b1 ofs b2 delta,
+ mi b1 = Some(b2, delta) ->
+ mem_inj mi m1 m2 ->
+ valid_pointer m1 b1 ofs = true ->
+ valid_pointer m2 b2 (ofs + delta) = true.
+Proof.
+ intros. rewrite valid_pointer_valid_access in H1.
+ rewrite valid_pointer_valid_access. eauto with mem.
+Qed.
+
+End GENERIC_INJECT.
+
+(** ** Store extensions *)
(** A store [m2] extends a store [m1] if [m2] can be obtained from [m1]
by increasing the sizes of the memory blocks of [m1] (decreasing
the low bounds, increasing the high bounds), while still keeping the
- same contents for block offsets that are valid in [m1].
- This notion is used in the proof of semantic equivalence in
- module [Machenv]. *)
+ same contents for block offsets that are valid in [m1]. *)
-Definition block_contents_extends (c1 c2: block_contents) :=
- c2.(low) <= c1.(low) /\ c1.(high) <= c2.(high) /\
- contentmap_agree c1.(low) c1.(high) c1.(contents) c2.(contents).
+Definition inject_id : meminj := fun b => Some(b, 0).
+
+Definition val_inj_id (mi: meminj) (v1 v2: val) : Prop := v1 = v2.
Definition extends (m1 m2: mem) :=
- m1.(nextblock) = m2.(nextblock) /\
- forall (b: block),
- b < m1.(nextblock) ->
- block_contents_extends (m1.(blocks) b) (m2.(blocks) b).
+ nextblock m1 = nextblock m2 /\ mem_inj val_inj_id inject_id m1 m2.
Theorem extends_refl:
forall (m: mem), extends m m.
Proof.
- intro. red. split.
- reflexivity.
- intros. red.
- split. omega. split. omega.
- red. intros. reflexivity.
+ intros; split. auto.
+ red; unfold inject_id; intros. inv H.
+ exists v1; split. replace (ofs + 0) with ofs by omega. auto.
+ unfold val_inj_id; auto.
Qed.
Theorem alloc_extends:
@@ -1293,16 +1519,18 @@ Theorem alloc_extends:
alloc m2 lo2 hi2 = (m2', b2) ->
b1 = b2 /\ extends m1' m2'.
Proof.
- unfold extends, alloc; intros.
- injection H2; intros; subst m1'; subst b1.
- injection H3; intros; subst m2'; subst b2.
- simpl. intuition.
- rewrite <- H4. case (zeq b (nextblock m1)); intro.
- subst b. repeat rewrite update_s.
- red; simpl. intuition.
- red; intros; reflexivity.
- repeat rewrite update_o. apply H5. omega.
- auto. auto.
+ intros. destruct H.
+ assert (b1 = b2).
+ transitivity (nextblock m1). eapply alloc_result; eauto.
+ symmetry. rewrite H. eapply alloc_result; eauto.
+ subst b2. split. auto. split.
+ rewrite (nextblock_alloc _ _ _ _ _ H2).
+ rewrite (nextblock_alloc _ _ _ _ _ H3).
+ congruence.
+ eapply alloc_parallel_inj; eauto.
+ unfold val_inj_id; auto.
+ unfold inject_id; eauto.
+ omega. omega.
Qed.
Theorem free_extends:
@@ -1310,16 +1538,11 @@ Theorem free_extends:
extends m1 m2 ->
extends (free m1 b) (free m2 b).
Proof.
- unfold extends, free; intros.
- simpl. intuition.
- red; intros; simpl.
- case (zeq b0 b); intro.
- subst b0; repeat (rewrite update_s).
- simpl. split. omega. split. omega.
- red. intros. omegaContradiction.
- repeat (rewrite update_o).
- exact (H1 b0 H).
- auto. auto.
+ intros. destruct H. split.
+ simpl; auto.
+ eapply free_parallel_inj; eauto.
+ unfold inject_id. eauto.
+ unfold inject_id; intros. congruence.
Qed.
Theorem load_extends:
@@ -1328,18 +1551,10 @@ Theorem load_extends:
load chunk m1 b ofs = Some v ->
load chunk m2 b ofs = Some v.
Proof.
- intros sz m1 m2 b ofs v (X, Y) L.
- generalize (load_inv _ _ _ _ _ L).
- intros (A, (B, (C, D))).
- unfold load. rewrite <- X. rewrite zlt_true; auto.
- generalize (Y b A); intros [M [P Q]].
- rewrite in_bounds_holds.
- rewrite <- D.
- decEq. decEq.
- apply load_contentmap_agree with
- (lo := low((blocks m1) b))
- (hi := high((blocks m1) b)); auto.
- omega. omega.
+ intros. destruct H.
+ exploit H1; eauto. unfold inject_id. eauto.
+ unfold val_inj_id. intros [v2 [LOAD EQ]].
+ replace (ofs + 0) with ofs in LOAD by omega. congruence.
Qed.
Theorem store_within_extends:
@@ -1348,24 +1563,21 @@ Theorem store_within_extends:
store chunk m1 b ofs v = Some m1' ->
exists m2', store chunk m2 b ofs v = Some m2' /\ extends m1' m2'.
Proof.
- intros sz m1 m2 m1' b ofs v (X, Y) STORE.
- generalize (store_inv _ _ _ _ _ _ STORE).
- intros (A, (B, (C, (D, (x, E))))).
- generalize (Y b A); intros [M [P Q]].
- unfold store. rewrite <- X. rewrite zlt_true; auto.
- case (in_bounds sz ofs (blocks m2 b)); intro.
- exists (unchecked_store sz m2 b ofs v a).
- split. auto.
+ intros. destruct H.
+ exploit store_mapped_inj; eauto.
+ unfold val_inj_id; eauto.
+ unfold meminj_no_overlap, inject_id; intros.
+ inv H3. inv H4. auto.
+ unfold inject_id; eauto.
+ unfold val_inj_id; intros. eauto.
+ intros [m2' [STORE MINJ]].
+ exists m2'; split.
+ replace (ofs + 0) with ofs in STORE by omega. auto.
split.
- unfold unchecked_store; simpl. congruence.
- intros b' LT.
- unfold block_contents_extends, unchecked_store, block_contents_agree.
- rewrite E; unfold update; simpl.
- case (zeq b' b); intro; simpl.
- subst b'. split. omega. split. omega.
- apply store_contentmap_agree. auto.
- apply Y. rewrite <- D. auto.
- omegaContradiction.
+ rewrite (nextblock_store _ _ _ _ _ _ H0).
+ rewrite (nextblock_store _ _ _ _ _ _ STORE).
+ auto.
+ auto.
Qed.
Theorem store_outside_extends:
@@ -1375,59 +1587,147 @@ Theorem store_outside_extends:
store chunk m2 b ofs v = Some m2' ->
extends m1 m2'.
Proof.
- intros sz m1 m2 m2' b ofs v (X, Y) BOUNDS STORE.
- generalize (store_inv _ _ _ _ _ _ STORE).
- intros (A, (B, (C, (D, (x, E))))).
- split.
- congruence.
- intros b' LT.
- rewrite E; unfold update; case (zeq b' b); intro.
- subst b'. generalize (Y b LT). intros [M [P Q]].
- red; simpl. split. omega. split. omega.
- apply store_contentmap_outside_agree.
- assumption. exact BOUNDS.
- auto.
-Qed.
-
-(** * Memory extensionality properties *)
-
-Lemma block_contents_exten:
- forall (c1 c2: block_contents),
- c1.(low) = c2.(low) ->
- c1.(high) = c2.(high) ->
- block_contents_agree c1.(low) c1.(high) c1 c2 ->
- c1 = c2.
-Proof.
- intros. caseEq c1; intros lo1 hi1 m1 UO1 EQ1. subst c1.
- caseEq c2; intros lo2 hi2 m2 UO2 EQ2. subst c2.
- simpl in *. subst lo2 hi2.
- assert (m1 = m2).
- unfold contentmap. apply extensionality. intro.
- case (zlt x lo1); intro.
- rewrite UO1. rewrite UO2. auto. tauto. tauto.
- case (zlt x hi1); intro.
- apply H1. omega.
- rewrite UO1. rewrite UO2. auto. tauto. tauto.
- subst m2.
- assert (UO1 = UO2).
- apply proof_irrelevance.
- subst UO2. reflexivity.
-Qed.
-
-Theorem mem_exten:
- forall m1 m2,
- m1.(nextblock) = m2.(nextblock) ->
- (forall b, m1.(blocks) b = m2.(blocks) b) ->
- m1 = m2.
-Proof.
- intros. destruct m1 as [map1 nb1 nextpos1]. destruct m2 as [map2 nb2 nextpos2].
- simpl in *. subst nb2.
- assert (map1 = map2). apply extensionality. assumption.
- assert (nextpos1 = nextpos2). apply proof_irrelevance.
+ intros. destruct H. split.
+ rewrite (nextblock_store _ _ _ _ _ _ H1). auto.
+ eapply store_outside_inj; eauto.
+ unfold inject_id; intros. inv H3. omega.
+Qed.
+
+Theorem valid_pointer_extends:
+ forall m1 m2 b ofs,
+ extends m1 m2 -> valid_pointer m1 b ofs = true ->
+ valid_pointer m2 b ofs = true.
+Proof.
+ intros. destruct H.
+ replace ofs with (ofs + 0) by omega.
+ apply valid_pointer_inj with val_inj_id inject_id m1 b; auto.
+Qed.
+
+(** * The ``less defined than'' relation over memory states *)
+
+(** A memory state [m1] is less defined than [m2] if, for all addresses,
+ the value [v1] read in [m1] at this address is less defined than
+ the value [v2] read in [m2], that is, either [v1 = v2] or [v1 = Vundef]. *)
+
+Definition val_inj_lessdef (mi: meminj) (v1 v2: val) : Prop :=
+ Val.lessdef v1 v2.
+
+Definition lessdef (m1 m2: mem) : Prop :=
+ nextblock m1 = nextblock m2 /\
+ mem_inj val_inj_lessdef inject_id m1 m2.
+
+Lemma lessdef_refl:
+ forall m, lessdef m m.
+Proof.
+ intros; split. auto.
+ red; intros. unfold inject_id in H. inv H.
+ exists v1; split. replace (ofs + 0) with ofs by omega. auto.
+ red. constructor.
+Qed.
+
+Lemma load_lessdef:
+ forall m1 m2 chunk b ofs v1,
+ lessdef m1 m2 -> load chunk m1 b ofs = Some v1 ->
+ exists v2, load chunk m2 b ofs = Some v2 /\ Val.lessdef v1 v2.
+Proof.
+ intros. destruct H.
+ exploit H1; eauto. unfold inject_id. eauto.
+ intros [v2 [LOAD INJ]]. exists v2; split.
+ replace ofs with (ofs + 0) by omega. auto.
+ auto.
+Qed.
+
+Lemma loadv_lessdef:
+ forall m1 m2 chunk addr1 addr2 v1,
+ lessdef m1 m2 -> Val.lessdef addr1 addr2 ->
+ loadv chunk m1 addr1 = Some v1 ->
+ exists v2, loadv chunk m2 addr2 = Some v2 /\ Val.lessdef v1 v2.
+Proof.
+ intros. inv H0.
+ destruct addr2; simpl in *; try discriminate.
+ eapply load_lessdef; eauto.
+ simpl in H1; discriminate.
+Qed.
+
+Lemma store_lessdef:
+ forall m1 m2 chunk b ofs v1 v2 m1',
+ lessdef m1 m2 -> Val.lessdef v1 v2 ->
+ store chunk m1 b ofs v1 = Some m1' ->
+ exists m2', store chunk m2 b ofs v2 = Some m2' /\ lessdef m1' m2'.
+Proof.
+ intros. destruct H.
+ exploit store_mapped_inj; eauto.
+ unfold val_inj_lessdef; intros; constructor.
+ red; unfold inject_id; intros. inv H4. inv H5. auto.
+ unfold inject_id; eauto.
+ unfold val_inj_lessdef; intros.
+ apply Val.load_result_lessdef. eexact H0.
+ intros [m2' [STORE MINJ]].
+ exists m2'; split. replace ofs with (ofs + 0) by omega. auto.
+ split.
+ rewrite (nextblock_store _ _ _ _ _ _ H1).
+ rewrite (nextblock_store _ _ _ _ _ _ STORE).
+ auto.
+ auto.
+Qed.
+
+Lemma storev_lessdef:
+ forall m1 m2 chunk addr1 v1 addr2 v2 m1',
+ lessdef m1 m2 -> Val.lessdef addr1 addr2 -> Val.lessdef v1 v2 ->
+ storev chunk m1 addr1 v1 = Some m1' ->
+ exists m2', storev chunk m2 addr2 v2 = Some m2' /\ lessdef m1' m2'.
+Proof.
+ intros. inv H0.
+ destruct addr2; simpl in H2; try discriminate.
+ simpl. eapply store_lessdef; eauto.
+ discriminate.
+Qed.
+
+Lemma alloc_lessdef:
+ forall m1 m2 lo hi b1 m1' b2 m2',
+ lessdef m1 m2 -> alloc m1 lo hi = (m1', b1) -> alloc m2 lo hi = (m2', b2) ->
+ b1 = b2 /\ lessdef m1' m2'.
+Proof.
+ intros. destruct H.
+ assert (b1 = b2).
+ transitivity (nextblock m1). eapply alloc_result; eauto.
+ symmetry. rewrite H. eapply alloc_result; eauto.
+ subst b2. split. auto. split.
+ rewrite (nextblock_alloc _ _ _ _ _ H0).
+ rewrite (nextblock_alloc _ _ _ _ _ H1).
congruence.
+ eapply alloc_parallel_inj; eauto.
+ unfold val_inj_lessdef; auto.
+ unfold inject_id; eauto.
+ omega. omega.
Qed.
-(** * Store injections *)
+Lemma free_lessdef:
+ forall m1 m2 b, lessdef m1 m2 -> lessdef (free m1 b) (free m2 b).
+Proof.
+ intros. destruct H. split.
+ simpl; auto.
+ eapply free_parallel_inj; eauto.
+ unfold inject_id. eauto.
+ unfold inject_id; intros. congruence.
+Qed.
+
+Lemma valid_block_lessdef:
+ forall m1 m2 b, lessdef m1 m2 -> valid_block m1 b -> valid_block m2 b.
+Proof.
+ unfold valid_block. intros. destruct H. rewrite <- H; auto.
+Qed.
+
+Lemma valid_pointer_lessdef:
+ forall m1 m2 b ofs,
+ lessdef m1 m2 -> valid_pointer m1 b ofs = true -> valid_pointer m2 b ofs = true.
+Proof.
+ intros. destruct H.
+ replace ofs with (ofs + 0) by omega.
+ apply valid_pointer_inj with val_inj_lessdef inject_id m1 b; auto.
+Qed.
+
+(** ** Memory injections *)
(** A memory injection [f] is a function from addresses to either [None]
or [Some] of an address and an offset. It defines a correspondence
@@ -1437,718 +1737,358 @@ Qed.
a sub-block at offset [ofs] of the block [b'] in [m2].
*)
-Definition meminj := (block -> option (block * Z))%type.
-
-Section MEM_INJECT.
-
-Variable f: meminj.
-
(** A memory injection defines a relation between values that is the
identity relation, except for pointer values which are shifted
as prescribed by the memory injection. *)
-Inductive val_inject: val -> val -> Prop :=
+Inductive val_inject (mi: meminj): val -> val -> Prop :=
| val_inject_int:
- forall i, val_inject (Vint i) (Vint i)
+ forall i, val_inject mi (Vint i) (Vint i)
| val_inject_float:
- forall f, val_inject (Vfloat f) (Vfloat f)
+ forall f, val_inject mi (Vfloat f) (Vfloat f)
| val_inject_ptr:
forall b1 ofs1 b2 ofs2 x,
- f b1 = Some (b2, x) ->
+ mi b1 = Some (b2, x) ->
ofs2 = Int.add ofs1 (Int.repr x) ->
- val_inject (Vptr b1 ofs1) (Vptr b2 ofs2)
+ val_inject mi (Vptr b1 ofs1) (Vptr b2 ofs2)
| val_inject_undef: forall v,
- val_inject Vundef v.
+ val_inject mi Vundef v.
Hint Resolve val_inject_int val_inject_float val_inject_ptr
-val_inject_undef.
+ val_inject_undef.
-Inductive val_list_inject: list val -> list val-> Prop:=
+Inductive val_list_inject (mi: meminj): list val -> list val-> Prop:=
| val_nil_inject :
- val_list_inject nil nil
+ val_list_inject mi nil nil
| val_cons_inject : forall v v' vl vl' ,
- val_inject v v' -> val_list_inject vl vl'->
- val_list_inject (v::vl) (v':: vl').
-
-Inductive val_content_inject: memory_size -> val -> val -> Prop :=
- | val_content_inject_base:
- forall sz v1 v2,
- val_inject v1 v2 ->
- val_content_inject sz v1 v2
- | val_content_inject_8:
- forall n1 n2,
- Int.cast8unsigned n1 = Int.cast8unsigned n2 ->
- val_content_inject Size8 (Vint n1) (Vint n2)
- | val_content_inject_16:
- forall n1 n2,
- Int.cast16unsigned n1 = Int.cast16unsigned n2 ->
- val_content_inject Size16 (Vint n1) (Vint n2)
- | val_content_inject_32:
- forall f1 f2,
- Float.singleoffloat f1 = Float.singleoffloat f2 ->
- val_content_inject Size32 (Vfloat f1) (Vfloat f2).
+ val_inject mi v v' -> val_list_inject mi vl vl'->
+ val_list_inject mi (v :: vl) (v' :: vl').
-Hint Resolve val_content_inject_base.
-
-Inductive content_inject: content -> content -> Prop :=
- | content_inject_undef:
- forall c,
- content_inject Undef c
- | content_inject_datum8:
- forall v1 v2,
- val_content_inject Size8 v1 v2 ->
- content_inject (Datum8 v1) (Datum8 v2)
- | content_inject_datum16:
- forall v1 v2,
- val_content_inject Size16 v1 v2 ->
- content_inject (Datum16 v1) (Datum16 v2)
- | content_inject_datum32:
- forall v1 v2,
- val_content_inject Size32 v1 v2 ->
- content_inject (Datum32 v1) (Datum32 v2)
- | content_inject_datum64:
- forall v1 v2,
- val_content_inject Size64 v1 v2 ->
- content_inject (Datum64 v1) (Datum64 v2)
- | content_inject_cont:
- content_inject Cont Cont.
-
-Hint Resolve content_inject_undef content_inject_datum8
-content_inject_datum16 content_inject_datum32 content_inject_datum64
-content_inject_cont.
-
-Definition contentmap_inject (c1 c2: contentmap) (lo hi delta: Z) : Prop :=
- forall x, lo <= x < hi ->
- content_inject (c1 x) (c2 (x + delta)).
-
-(** A block contents [c1] injects into another block content [c2] at
- offset [delta] if the contents of [c1] at all valid offsets
- correspond to the contents of [c2] at the same offsets shifted by [delta].
- Some additional conditions are imposed to guard against arithmetic
- overflow in address computations. *)
-
-Record block_contents_inject (c1 c2: block_contents) (delta: Z) : Prop :=
- mk_block_contents_inject {
- bci_range1: Int.min_signed <= delta <= Int.max_signed;
- bci_range2: delta = 0 \/
- (Int.min_signed <= c2.(low) /\ c2.(high) <= Int.max_signed);
- bci_lowhigh:forall x, c1.(low) <= x < c1.(high) ->
- c2.(low) <= x+delta < c2.(high) ;
- bci_contents:
- contentmap_inject c1.(contents) c2.(contents) c1.(low) c1.(high) delta
- }.
+Hint Resolve val_nil_inject val_cons_inject.
(** A memory state [m1] injects into another memory state [m2] via the
memory injection [f] if the following conditions hold:
+- loads in [m1] must have matching loads in [m2] in the sense
+ of the [mem_inj] predicate;
- unallocated blocks in [m1] must be mapped to [None] by [f];
-- if [f b = Some(b', delta)], [b'] must be valid in [m2] and
- the contents of [b] in [m1] must inject into the contents of [b'] in [m2]
- with offset [delta];
-- distinct blocks in [m1] cannot be mapped to overlapping sub-blocks in [m2].
+- if [f b = Some(b', delta)], [b'] must be valid in [m2];
+- distinct blocks in [m1] are mapped to non-overlapping sub-blocks in [m2];
+- the sizes of [m2]'s blocks are representable with signed machine integers;
+- the offsets [delta] are representable with signed machine integers.
*)
-Record mem_inject (m1 m2: mem) : Prop :=
+Record mem_inject (f: meminj) (m1 m2: mem) : Prop :=
mk_mem_inject {
+ mi_inj:
+ mem_inj val_inject f m1 m2;
mi_freeblocks:
- forall b, b >= m1.(nextblock) -> f b = None;
+ forall b, ~(valid_block m1 b) -> f b = None;
mi_mappedblocks:
+ forall b b' delta, f b = Some(b', delta) -> valid_block m2 b';
+ mi_no_overlap:
+ meminj_no_overlap f m1;
+ mi_range_1:
forall b b' delta,
f b = Some(b', delta) ->
- b' < m2.(nextblock) /\
- block_contents_inject (m1.(blocks) b)
- (m2.(blocks) b')
- delta;
- mi_no_overlap:
- forall b1 b2 b1' b2' delta1 delta2,
- b1 <> b2 ->
- f b1 = Some (b1', delta1) ->
- f b2 = Some (b2', delta2) ->
- b1' <> b2'
- \/ (forall x1 x2, low_bound m1 b1 <= x1 < high_bound m1 b1 ->
- low_bound m1 b2 <= x2 < high_bound m1 b2 ->
- x1+delta1 <> x2+delta2)
- }.
+ Int.min_signed <= delta <= Int.max_signed;
+ mi_range_2:
+ forall b b' delta,
+ f b = Some(b', delta) ->
+ delta = 0 \/ (Int.min_signed <= low_bound m2 b' /\ high_bound m2 b' <= Int.max_signed)
+ }.
+
(** The following lemmas establish the absence of machine integer overflow
during address computations. *)
-Lemma size_mem_pos: forall sz, size_mem sz > 0.
-Proof. destruct sz; simpl; omega. Qed.
-
-Lemma size_chunk_pos: forall chunk, size_chunk chunk > 0.
-Proof. intros. unfold size_chunk. apply size_mem_pos. Qed.
-
Lemma address_inject:
- forall m1 m2 chunk b1 ofs1 b2 ofs2 x,
- mem_inject m1 m2 ->
- (m1.(blocks) b1).(low) <= Int.signed ofs1 ->
- Int.signed ofs1 + size_chunk chunk <= (m1.(blocks) b1).(high) ->
- f b1 = Some (b2, x) ->
- ofs2 = Int.add ofs1 (Int.repr x) ->
- Int.signed ofs2 = Int.signed ofs1 + x.
+ forall f m1 m2 chunk b1 ofs1 b2 delta,
+ mem_inject f m1 m2 ->
+ valid_access m1 chunk b1 (Int.signed ofs1) ->
+ f b1 = Some (b2, delta) ->
+ Int.signed (Int.add ofs1 (Int.repr delta)) = Int.signed ofs1 + delta.
Proof.
- intros.
- generalize (size_chunk_pos chunk). intro.
- generalize (mi_mappedblocks m1 m2 H _ _ _ H2). intros [C D].
- inversion D.
- elim bci_range4 ; intro.
- (**x=0**)
- subst x . rewrite Zplus_0_r. rewrite Int.add_zero in H3.
- subst ofs2 ; auto .
- (**x<>0**)
- rewrite H3. rewrite Int.add_signed. repeat rewrite Int.signed_repr.
- auto. auto.
- assert (low (blocks m1 b1) <= Int.signed ofs1 < high (blocks m1 b1)).
- omega.
- generalize (bci_lowhigh0 (Int.signed ofs1) H6). omega.
- auto.
+ intros. inversion H.
+ elim (mi_range_4 _ _ _ H1); intro.
+ (* delta = 0 *)
+ subst delta. change (Int.repr 0) with Int.zero.
+ rewrite Int.add_zero. omega.
+ (* delta <> 0 *)
+ rewrite Int.add_signed.
+ repeat rewrite Int.signed_repr. auto.
+ eauto.
+ assert (valid_access m2 chunk b2 (Int.signed ofs1 + delta)).
+ eapply valid_access_inj; eauto.
+ inv H3. generalize (size_chunk_pos chunk); omega.
+ eauto.
Qed.
Lemma valid_pointer_inject_no_overflow:
- forall m1 m2 b ofs b' x,
- mem_inject m1 m2 ->
+ forall f m1 m2 b ofs b' x,
+ mem_inject f m1 m2 ->
valid_pointer m1 b (Int.signed ofs) = true ->
f b = Some(b', x) ->
Int.min_signed <= Int.signed ofs + Int.signed (Int.repr x) <= Int.max_signed.
Proof.
- intros. unfold valid_pointer in H0.
- destruct (zlt b (nextblock m1)); try discriminate.
- destruct (zle (low (blocks m1 b)) (Int.signed ofs)); try discriminate.
- destruct (zlt (Int.signed ofs) (high (blocks m1 b))); try discriminate.
- inversion H. generalize (mi_mappedblocks0 _ _ _ H1).
- intros [A B]. inversion B.
- elim bci_range4 ; intro.
- (**x=0**)
- rewrite Int.signed_repr ; auto.
- subst x . rewrite Zplus_0_r. apply Int.signed_range .
- (**x<>0**)
- generalize (bci_lowhigh0 _ (conj z0 z1)). intro.
- rewrite Int.signed_repr. omega. auto.
-Qed.
-
-(** Relation between injections and loads. *)
-
-Lemma check_cont_inject:
- forall c1 c2 lo hi delta,
- contentmap_inject c1 c2 lo hi delta ->
- forall n p,
- lo <= p -> p + Z_of_nat n <= hi ->
- check_cont n p c1 = true ->
- check_cont n (p + delta) c2 = true.
-Proof.
- induction n.
- intros. simpl. reflexivity.
- simpl check_cont. rewrite inj_S. intros p H0 H1.
- assert (lo <= p < hi). omega.
- generalize (H p H2). intro. inversion H3; intros; try discriminate.
- replace (p + delta + 1) with ((p + 1) + delta).
- apply IHn. omega. omega. auto.
+ intros. inv H. rewrite valid_pointer_valid_access in H0.
+ assert (valid_access m2 Mint8unsigned b' (Int.signed ofs + x)).
+ eapply valid_access_inj; eauto.
+ inv H. change (size_chunk Mint8unsigned) with 1 in H4.
+ rewrite Int.signed_repr; eauto.
+ exploit mi_range_4; eauto. intros [A | [A B]].
+ subst x. rewrite Zplus_0_r. apply Int.signed_range.
omega.
Qed.
-Hint Resolve check_cont_inject.
-
-Lemma getN_inject:
- forall c1 c2 lo hi delta,
- contentmap_inject c1 c2 lo hi delta ->
- forall n p,
- lo <= p -> p + Z_of_nat n < hi ->
- content_inject (getN n p c1) (getN n (p + delta) c2).
-Proof.
- intros. simpl in H1.
- assert (lo <= p < hi). omega.
- unfold getN.
- caseEq (check_cont n (p + 1) c1); intro.
- replace (check_cont n (p + delta + 1) c2) with true.
- apply H. assumption.
- symmetry. replace (p + delta + 1) with ((p + 1) + delta).
- eapply check_cont_inject; eauto.
- omega. omega. omega.
- constructor.
-Qed.
-
-Hint Resolve getN_inject.
-
-Definition ztonat (z:Z): nat:=
-match z with
-| Z0 => O
-| Zpos p => (nat_of_P p)
-| Zneg p =>O
-end.
-
-Lemma load_contents_inject:
- forall sz c1 c2 lo hi delta p,
- contentmap_inject c1 c2 lo hi delta ->
- lo <= p -> p + size_mem sz <= hi ->
- val_content_inject sz (load_contents sz c1 p) (load_contents sz c2 (p + delta)).
-Proof.
-intros.
-assert (content_inject (getN (ztonat (size_mem sz)-1) p c1)
-(getN (ztonat(size_mem sz)-1) (p + delta) c2)).
-induction sz; assert (lo<= p< hi); simpl in H1; try omega;
-apply getN_inject with lo hi; try assumption; simpl ; try omega.
-induction sz ; simpl; inversion H2; auto.
-Qed.
-
-Hint Resolve load_contents_inject.
-
-Lemma load_result_inject:
- forall chunk v1 v2,
- val_content_inject (mem_chunk chunk) v1 v2 ->
- val_inject (Val.load_result chunk v1) (Val.load_result chunk v2).
-Proof.
-intros.
-destruct chunk; simpl in H; inversion H; simpl; auto;
-try (inversion H0; simpl; auto; fail).
-replace (Int.cast8signed n2) with (Int.cast8signed n1). constructor.
-apply Int.cast8_signed_equal_if_unsigned_equal; auto.
-rewrite H0; constructor.
-replace (Int.cast16signed n2) with (Int.cast16signed n1). constructor.
-apply Int.cast16_signed_equal_if_unsigned_equal; auto.
-rewrite H0; constructor.
-inversion H0; simpl; auto.
-apply val_inject_ptr with x; auto.
-Qed.
-
-Lemma in_bounds_inject:
- forall chunk c1 c2 delta p,
- block_contents_inject c1 c2 delta ->
- c1.(low) <= p /\ p + size_chunk chunk <= c1.(high) ->
- c2.(low) <= p + delta /\ (p + delta) + size_chunk chunk <= c2.(high).
+Lemma valid_pointer_inject:
+ forall f m1 m2 b ofs b' ofs',
+ mem_inject f m1 m2 ->
+ valid_pointer m1 b (Int.signed ofs) = true ->
+ val_inject f (Vptr b ofs) (Vptr b' ofs') ->
+ valid_pointer m2 b' (Int.signed ofs') = true.
Proof.
- intros.
- inversion H.
- generalize (size_chunk_pos chunk); intro.
- assert (low c1 <= p + size_chunk chunk - 1 < high c1).
- omega.
- generalize (bci_lowhigh0 _ H2). intro.
- assert (low c1 <= p < high c1).
- omega.
- generalize (bci_lowhigh0 _ H4). intro.
- omega.
+ intros. inv H1.
+ exploit valid_pointer_inject_no_overflow; eauto. intro NOOV.
+ inv H. rewrite Int.add_signed. rewrite Int.signed_repr; auto.
+ rewrite Int.signed_repr; eauto.
+ eapply valid_pointer_inj; eauto.
Qed.
-Lemma block_cont_val:
-forall c1 c2 delta p sz,
-block_contents_inject c1 c2 delta ->
-c1.(low) <= p -> p + size_mem sz <= c1.(high) ->
- val_content_inject sz (load_contents sz c1.(contents) p)
- (load_contents sz c2.(contents) (p + delta)).
-Proof.
-intros.
-inversion H .
-apply load_contents_inject with c1.(low) c1.(high) ;assumption.
-Qed.
+(** Relation between injections and loads. *)
Lemma load_inject:
- forall m1 m2 chunk b1 ofs b2 delta v1,
- mem_inject m1 m2 ->
+ forall f m1 m2 chunk b1 ofs b2 delta v1,
+ mem_inject f m1 m2 ->
load chunk m1 b1 ofs = Some v1 ->
f b1 = Some (b2, delta) ->
- exists v2, load chunk m2 b2 (ofs + delta) = Some v2 /\ val_inject v1 v2.
+ exists v2, load chunk m2 b2 (ofs + delta) = Some v2 /\ val_inject f v1 v2.
Proof.
- intros.
- generalize (load_inv _ _ _ _ _ H0). intros [A [B [C D]]].
- inversion H.
- generalize (mi_mappedblocks0 _ _ _ H1). intros [U V].
- inversion V.
- exists (Val.load_result chunk (load_contents (mem_chunk chunk)
- (m2.(blocks) b2).(contents) (ofs+delta))).
- split.
- unfold load.
- generalize (size_chunk_pos chunk); intro.
- rewrite zlt_true. rewrite in_bounds_holds. auto.
- assert (low (blocks m1 b1) <= ofs < high (blocks m1 b1)).
- omega.
- generalize (bci_lowhigh0 _ H3). tauto.
- assert (low (blocks m1 b1) <= ofs + size_chunk chunk - 1 < high(blocks m1 b1)).
- omega.
- generalize (bci_lowhigh0 _ H3). omega.
- assumption.
- rewrite <- D. apply load_result_inject.
- eapply load_contents_inject; eauto.
+ intros. inversion H.
+ eapply mi_inj0; eauto.
Qed.
Lemma loadv_inject:
- forall m1 m2 chunk a1 a2 v1,
- mem_inject m1 m2 ->
+ forall f m1 m2 chunk a1 a2 v1,
+ mem_inject f m1 m2 ->
loadv chunk m1 a1 = Some v1 ->
- val_inject a1 a2 ->
- exists v2, loadv chunk m2 a2 = Some v2 /\ val_inject v1 v2.
+ val_inject f a1 a2 ->
+ exists v2, loadv chunk m2 a2 = Some v2 /\ val_inject f v1 v2.
Proof.
- intros.
- induction H1 ; simpl in H0 ; try discriminate H0.
- simpl.
- replace (Int.signed ofs2) with (Int.signed ofs1 + x).
- apply load_inject with m1 b1 ; assumption.
- symmetry. generalize (load_inv _ _ _ _ _ H0). intros [A [B [C D]]].
- apply address_inject with m1 m2 chunk b1 b2; auto.
+ intros. inv H1; simpl in H0; try discriminate.
+ exploit load_inject; eauto. intros [v2 [LOAD INJ]].
+ exists v2; split; auto. simpl.
+ replace (Int.signed (Int.add ofs1 (Int.repr x)))
+ with (Int.signed ofs1 + x).
+ auto. symmetry. eapply address_inject; eauto with mem.
Qed.
(** Relation between injections and stores. *)
-Lemma set_cont_inject:
- forall c1 c2 lo hi delta,
- contentmap_inject c1 c2 lo hi delta ->
- forall n p,
- lo <= p -> p + Z_of_nat n <= hi ->
- contentmap_inject (set_cont n p c1) (set_cont n (p + delta) c2) lo hi delta.
-Proof.
-induction n. intros. simpl. assumption.
-intros. simpl. unfold contentmap_inject.
-intros p2 Hp2. unfold update.
-case (zeq p2 p); intro.
-subst p2. rewrite zeq_true. constructor.
-rewrite zeq_false. replace (p + delta + 1) with ((p + 1) + delta).
-apply IHn. omega. rewrite inj_S in H1. omega. assumption.
-omega. omega.
-Qed.
-
-Lemma setN_inject:
- forall c1 c2 lo hi delta n p v1 v2,
- contentmap_inject c1 c2 lo hi delta ->
- content_inject v1 v2 ->
- lo <= p -> p + Z_of_nat n < hi ->
- contentmap_inject (setN n p v1 c1) (setN n (p + delta) v2 c2)
- lo hi delta.
-Proof.
- intros. unfold setN. red; intros.
- unfold update.
- case (zeq x p); intro.
- subst p. rewrite zeq_true. assumption.
- rewrite zeq_false.
- replace (p + delta + 1) with ((p + 1) + delta).
- apply set_cont_inject with lo hi.
- assumption. omega. omega. assumption. omega.
- omega.
-Qed.
-
-Lemma store_contents_inject:
- forall c1 c2 lo hi delta sz p v1 v2,
- contentmap_inject c1 c2 lo hi delta ->
- val_content_inject sz v1 v2 ->
- lo <= p -> p + size_mem sz <= hi ->
- contentmap_inject (store_contents sz c1 p v1)
- (store_contents sz c2 (p + delta) v2)
- lo hi delta.
-Proof.
- intros.
- destruct sz; simpl in *; apply setN_inject; auto; simpl; omega.
-Qed.
-
-Lemma set_cont_outside1 :
- forall n p m q ,
- (forall x , p <= x < p + Z_of_nat n -> x <> q) ->
- (set_cont n p m) q = m q.
-Proof.
- induction n; intros; simpl.
- auto.
- rewrite inj_S in H. rewrite update_o. apply IHn.
- intros. apply H. omega.
- apply H. omega.
-Qed.
-
-Lemma set_cont_outside_inject:
- forall c1 c2 lo hi delta,
- contentmap_inject c1 c2 lo hi delta ->
- forall n p,
- (forall x1 x2, p <= x1 < p + Z_of_nat n ->
- lo <= x2 < hi ->
- x1 <> x2 + delta) ->
- contentmap_inject c1 (set_cont n p c2) lo hi delta.
-Proof.
- unfold contentmap_inject. intros.
- rewrite set_cont_outside1. apply H. assumption.
- intros. apply H0. auto. auto.
-Qed.
-
-Lemma setN_outside_inject:
- forall n c1 c2 lo hi delta p v,
- contentmap_inject c1 c2 lo hi delta ->
- (forall x1 x2, p <= x1 < p + Z_of_nat (S n) ->
- lo <= x2 < hi ->
- x1 <> x2 + delta) ->
- contentmap_inject c1 (setN n p v c2) lo hi delta.
-Proof.
- intros. unfold setN. red; intros. rewrite update_o.
- apply set_cont_outside_inject with lo hi. auto.
- intros. apply H0. rewrite inj_S. omega. auto. auto.
- apply H0. rewrite inj_S. omega. auto.
-Qed.
+Inductive val_content_inject (f: meminj): memory_chunk -> val -> val -> Prop :=
+ | val_content_inject_base:
+ forall chunk v1 v2,
+ val_inject f v1 v2 ->
+ val_content_inject f chunk v1 v2
+ | val_content_inject_8:
+ forall chunk n1 n2,
+ chunk = Mint8unsigned \/ chunk = Mint8signed ->
+ Int.cast8unsigned n1 = Int.cast8unsigned n2 ->
+ val_content_inject f chunk (Vint n1) (Vint n2)
+ | val_content_inject_16:
+ forall chunk n1 n2,
+ chunk = Mint16unsigned \/ chunk = Mint16signed ->
+ Int.cast16unsigned n1 = Int.cast16unsigned n2 ->
+ val_content_inject f chunk (Vint n1) (Vint n2)
+ | val_content_inject_32:
+ forall f1 f2,
+ Float.singleoffloat f1 = Float.singleoffloat f2 ->
+ val_content_inject f Mfloat32 (Vfloat f1) (Vfloat f2).
-Lemma store_contents_outside_inject:
- forall c1 c2 lo hi delta sz p v,
- contentmap_inject c1 c2 lo hi delta ->
- (forall x1 x2, p <= x1 < p + size_mem sz ->
- lo <= x2 < hi ->
- x1 <> x2 + delta)->
- contentmap_inject c1 (store_contents sz c2 p v) lo hi delta.
-Proof.
- intros c1 c2 lo hi delta sz. generalize (size_mem_pos sz) . intro .
- induction sz ;intros ;simpl ; apply setN_outside_inject ; assumption .
-Qed.
+Hint Resolve val_content_inject_base.
-Lemma store_mapped_inject_1:
- forall chunk m1 b1 ofs v1 n1 m2 b2 delta v2,
- mem_inject m1 m2 ->
+Lemma load_result_inject:
+ forall f chunk v1 v2 chunk',
+ val_content_inject f chunk v1 v2 ->
+ size_chunk chunk = size_chunk chunk' ->
+ val_inject f (Val.load_result chunk' v1) (Val.load_result chunk' v2).
+Proof.
+ intros. inv H; simpl.
+ inv H1; destruct chunk'; simpl; econstructor; eauto.
+
+ elim H1; intro; subst chunk;
+ destruct chunk'; simpl in H0; try discriminate; simpl.
+ replace (Int.cast8signed n1) with (Int.cast8signed n2).
+ constructor. apply Int.cast8_signed_equal_if_unsigned_equal; auto.
+ rewrite H2. constructor.
+ replace (Int.cast8signed n1) with (Int.cast8signed n2).
+ constructor. apply Int.cast8_signed_equal_if_unsigned_equal; auto.
+ rewrite H2. constructor.
+
+ elim H1; intro; subst chunk;
+ destruct chunk'; simpl in H0; try discriminate; simpl.
+ replace (Int.cast16signed n1) with (Int.cast16signed n2).
+ constructor. apply Int.cast16_signed_equal_if_unsigned_equal; auto.
+ rewrite H2. constructor.
+ replace (Int.cast16signed n1) with (Int.cast16signed n2).
+ constructor. apply Int.cast16_signed_equal_if_unsigned_equal; auto.
+ rewrite H2. constructor.
+
+ destruct chunk'; simpl in H0; try discriminate; simpl.
+ constructor. rewrite H1; constructor.
+Qed.
+
+Lemma store_mapped_inject_1 :
+ forall f chunk m1 b1 ofs v1 n1 m2 b2 delta v2,
+ mem_inject f m1 m2 ->
store chunk m1 b1 ofs v1 = Some n1 ->
f b1 = Some (b2, delta) ->
- val_content_inject (mem_chunk chunk) v1 v2 ->
+ val_content_inject f chunk v1 v2 ->
exists n2,
store chunk m2 b2 (ofs + delta) v2 = Some n2
- /\ mem_inject n1 n2.
-Proof.
-intros.
-generalize (size_chunk_pos chunk); intro SIZEPOS.
-generalize (store_inv _ _ _ _ _ _ H0).
-intros [A [B [C [D [P E]]]]].
-inversion H.
-generalize (mi_mappedblocks0 _ _ _ H1). intros [U V].
-inversion V.
-generalize (in_bounds_inject _ _ _ _ _ V (conj B C)). intro BND.
-exists (unchecked_store chunk m2 b2 (ofs+delta) v2 BND).
-split. unfold store.
-rewrite zlt_true; auto.
-case (in_bounds chunk (ofs + delta) (blocks m2 b2)); intro.
-assert (a = BND). apply proof_irrelevance. congruence.
-omegaContradiction.
-constructor.
-intros. apply mi_freeblocks0. rewrite <- D. assumption.
-intros. generalize (mi_mappedblocks0 b b' delta0 H3).
-intros [W Y]. split. simpl. auto.
-rewrite E; simpl. unfold update.
-(* Cas 1: memes blocs b = b1 b'= b2 *)
-case (zeq b b1); intro.
-subst b. assert (b'= b2). congruence. subst b'.
-assert (delta0 = delta). congruence. subst delta0.
-rewrite zeq_true. inversion Y. constructor; simpl; auto.
-apply store_contents_inject; auto.
-(* Cas 2: blocs differents dans m1 mais mappes sur le meme bloc de m2 *)
-case (zeq b' b2); intro.
-subst b'.
-inversion Y. constructor; simpl; auto.
-generalize (store_contents_outside_inject _ _ _ _ _ (mem_chunk chunk)
- (ofs+delta) v2 bci_contents1).
-intros.
-apply H4.
-elim (mi_no_overlap0 b b1 b2 b2 delta0 delta n H3 H1).
-tauto.
-unfold high_bound, low_bound. intros.
-apply sym_not_equal. replace x1 with ((x1 - delta) + delta).
-apply H5. assumption. unfold size_chunk in C. omega. omega.
-(* Cas 3: blocs differents dans m1 et dans m2 *)
-auto.
-
-unfold high_bound, low_bound.
-rewrite E; simpl; intros.
-unfold high_bound, low_bound in mi_no_overlap0.
-unfold update.
-case (zeq b0 b1).
-intro. subst b1. simpl.
-rewrite zeq_false; auto.
-intro. case (zeq b3 b1); intro.
-subst b3. simpl. auto.
-auto.
+ /\ mem_inject f n1 n2.
+Proof.
+ intros. inversion H.
+ exploit store_mapped_inj; eauto.
+ intros; constructor.
+ intros. apply load_result_inject with chunk; eauto.
+ intros [n2 [STORE MINJ]].
+ exists n2; split. auto. constructor.
+ (* inj *)
+ auto.
+ (* freeblocks *)
+ intros. apply mi_freeblocks0. red; intro. elim H3. eauto with mem.
+ (* mappedblocks *)
+ intros. eauto with mem.
+ (* no_overlap *)
+ red; intros.
+ repeat rewrite (low_bound_store _ _ _ _ _ _ H0).
+ repeat rewrite (high_bound_store _ _ _ _ _ _ H0).
+ eapply mi_no_overlap0; eauto.
+ (* range *)
+ auto.
+ intros.
+ repeat rewrite (low_bound_store _ _ _ _ _ _ STORE).
+ repeat rewrite (high_bound_store _ _ _ _ _ _ STORE).
+ eapply mi_range_4; eauto.
Qed.
Lemma store_mapped_inject:
- forall chunk m1 b1 ofs v1 n1 m2 b2 delta v2,
- mem_inject m1 m2 ->
+ forall f chunk m1 b1 ofs v1 n1 m2 b2 delta v2,
+ mem_inject f m1 m2 ->
store chunk m1 b1 ofs v1 = Some n1 ->
f b1 = Some (b2, delta) ->
- val_inject v1 v2 ->
+ val_inject f v1 v2 ->
exists n2,
store chunk m2 b2 (ofs + delta) v2 = Some n2
- /\ mem_inject n1 n2.
+ /\ mem_inject f n1 n2.
Proof.
intros. eapply store_mapped_inject_1; eauto.
Qed.
Lemma store_unmapped_inject:
- forall chunk m1 b1 ofs v1 n1 m2,
- mem_inject m1 m2 ->
+ forall f chunk m1 b1 ofs v1 n1 m2,
+ mem_inject f m1 m2 ->
store chunk m1 b1 ofs v1 = Some n1 ->
f b1 = None ->
- mem_inject n1 m2.
-Proof.
-intros.
-inversion H.
-generalize (store_inv _ _ _ _ _ _ H0).
-intros [A [B [C [D [P E]]]]].
-constructor.
-rewrite D. assumption.
-intros. elim (mi_mappedblocks0 _ _ _ H2); intros.
-split. auto.
-rewrite E; unfold update.
-rewrite zeq_false. assumption.
-congruence.
-intros.
-assert (forall b, low_bound n1 b = low_bound m1 b).
- intros. unfold low_bound; rewrite E; unfold update.
- case (zeq b b1); intros. subst b1; reflexivity. reflexivity.
-assert (forall b, high_bound n1 b = high_bound m1 b).
- intros. unfold high_bound; rewrite E; unfold update.
- case (zeq b b1); intros. subst b1; reflexivity. reflexivity.
-repeat rewrite H5. repeat rewrite H6. auto.
+ mem_inject f n1 m2.
+Proof.
+ intros. inversion H.
+ constructor.
+ (* inj *)
+ eapply store_unmapped_inj; eauto.
+ (* freeblocks *)
+ intros. apply mi_freeblocks0. red; intros; elim H2; eauto with mem.
+ (* mappedblocks *)
+ intros. eapply mi_mappedblocks0; eauto with mem.
+ (* no_overlap *)
+ red; intros.
+ repeat rewrite (low_bound_store _ _ _ _ _ _ H0).
+ repeat rewrite (high_bound_store _ _ _ _ _ _ H0).
+ eapply mi_no_overlap0; eauto.
+ (* range *)
+ auto. auto.
Qed.
Lemma storev_mapped_inject_1:
- forall chunk m1 a1 v1 n1 m2 a2 v2,
- mem_inject m1 m2 ->
+ forall f chunk m1 a1 v1 n1 m2 a2 v2,
+ mem_inject f m1 m2 ->
storev chunk m1 a1 v1 = Some n1 ->
- val_inject a1 a2 ->
- val_content_inject (mem_chunk chunk) v1 v2 ->
+ val_inject f a1 a2 ->
+ val_content_inject f chunk v1 v2 ->
exists n2,
- storev chunk m2 a2 v2 = Some n2 /\ mem_inject n1 n2.
+ storev chunk m2 a2 v2 = Some n2 /\ mem_inject f n1 n2.
Proof.
- intros. destruct a1; simpl in H0; try discriminate.
- inversion H1. subst b.
- simpl. replace (Int.signed ofs2) with (Int.signed i + x).
+ intros. inv H1; simpl in H0; try discriminate.
+ simpl. replace (Int.signed (Int.add ofs1 (Int.repr x)))
+ with (Int.signed ofs1 + x).
eapply store_mapped_inject_1; eauto.
- symmetry. generalize (store_inv _ _ _ _ _ _ H0). intros [A [B [C [D [P E]]]]].
- apply address_inject with m1 m2 chunk b1 b2; auto.
+ symmetry. eapply address_inject; eauto with mem.
Qed.
Lemma storev_mapped_inject:
- forall chunk m1 a1 v1 n1 m2 a2 v2,
- mem_inject m1 m2 ->
+ forall f chunk m1 a1 v1 n1 m2 a2 v2,
+ mem_inject f m1 m2 ->
storev chunk m1 a1 v1 = Some n1 ->
- val_inject a1 a2 ->
- val_inject v1 v2 ->
+ val_inject f a1 a2 ->
+ val_inject f v1 v2 ->
exists n2,
- storev chunk m2 a2 v2 = Some n2 /\ mem_inject n1 n2.
+ storev chunk m2 a2 v2 = Some n2 /\ mem_inject f n1 n2.
Proof.
intros. eapply storev_mapped_inject_1; eauto.
Qed.
(** Relation between injections and [free] *)
-Lemma free_first_inject :
- forall m1 m2 b,
- mem_inject m1 m2 ->
- mem_inject (free m1 b) m2.
-Proof.
- intros. inversion H. constructor . auto.
- simpl. intros.
- generalize (mi_mappedblocks0 b0 b' delta H0).
- intros [A B] . split. assumption . unfold update.
- case (zeq b0 b); intro. inversion B. constructor; simpl; auto.
- intros. omega.
- unfold contentmap_inject.
- intros. omegaContradiction.
- auto. intros.
- unfold free . unfold low_bound , high_bound. simpl. unfold update.
- case (zeq b1 b);intro. simpl.
- right. intros. omegaContradiction.
- case (zeq b2 b);intro. simpl.
- right . intros. omegaContradiction.
- unfold low_bound, high_bound in mi_no_overlap0. auto.
-Qed.
-
-Lemma free_first_list_inject :
- forall l m1 m2,
- mem_inject m1 m2 ->
- mem_inject (free_list m1 l) m2.
-Proof.
- induction l; simpl; intros.
- auto.
- apply free_first_inject. auto.
-Qed.
-
-Lemma free_snd_inject:
- forall m1 m2 b,
- (forall b1 delta, f b1 = Some(b, delta) ->
- low_bound m1 b1 >= high_bound m1 b1) ->
- mem_inject m1 m2 ->
- mem_inject m1 (free m2 b).
-Proof.
- intros. inversion H0. constructor. auto.
- simpl. intros.
- generalize (mi_mappedblocks0 b0 b' delta H1).
- intros [A B] . split. assumption .
- inversion B. unfold update.
- case (zeq b' b); intro.
- subst b'. generalize (H _ _ H1). unfold low_bound, high_bound; intro.
- constructor. auto. elim bci_range4 ; intro.
- (**delta=0**)
- left ; auto .
- (** delta<>0**)
- right .
- simpl. compute. split; intro; congruence.
- intros. omegaContradiction.
- red; intros. omegaContradiction.
- auto.
- auto.
-Qed.
-
-Lemma bounds_free_block:
- forall m1 b m1' , free m1 b = m1' ->
- low_bound m1' b >= high_bound m1' b.
+Lemma meminj_no_overlap_free:
+ forall mi m b,
+ meminj_no_overlap mi m ->
+ meminj_no_overlap mi (free m b).
Proof.
- intros. unfold free in H.
- rewrite<- H . unfold low_bound , high_bound .
- simpl . rewrite update_s. simpl. omega.
+ intros; red; intros.
+ assert (low_bound (free m b) b >= high_bound (free m b) b).
+ rewrite low_bound_free_same; rewrite high_bound_free_same; auto.
+ omega.
+ destruct (eq_block b1 b); destruct (eq_block b2 b); subst; auto.
+ repeat (rewrite low_bound_free; auto).
+ repeat (rewrite high_bound_free; auto).
Qed.
-Lemma free_empty_bounds:
- forall l m1 ,
- let m1' := free_list m1 l in
- (forall b, In b l -> low_bound m1' b >= high_bound m1' b).
+Lemma meminj_no_overlap_free_list:
+ forall mi m bl,
+ meminj_no_overlap mi m ->
+ meminj_no_overlap mi (free_list m bl).
Proof.
- induction l . intros . inversion H.
- intros.
- generalize (in_inv H).
- intro . elim H0. intro . subst b. simpl in m1' .
- generalize ( bounds_free_block
- (fold_right (fun (b : block) (m : mem) => free m b) m1 l) a m1') .
- intros. apply H1. auto . intros. simpl in m1'. unfold m1' .
- unfold low_bound , high_bound . simpl .
- unfold update; case (zeq b a); intro; simpl.
- omega .
- unfold low_bound , high_bound in IHl . auto.
-Qed.
+ induction bl; simpl; intros. auto.
+ apply meminj_no_overlap_free. auto.
+Qed.
Lemma free_inject:
- forall m1 m2 l b,
+ forall f m1 m2 l b,
(forall b1 delta, f b1 = Some(b, delta) -> In b1 l) ->
- mem_inject m1 m2 ->
- mem_inject (free_list m1 l) (free m2 b).
-Proof.
- intros. apply free_snd_inject.
- intros. apply free_empty_bounds. apply H with delta. auto.
- apply free_first_list_inject. auto.
-Qed.
-
-Lemma contents_init_data_inject:
- forall id, contentmap_inject (contents_init_data 0 id) (contents_init_data 0 id) 0 (size_init_data_list id) 0.
-Proof.
- intro id0.
- set (sz0 := size_init_data_list id0).
- assert (forall id pos,
- 0 <= pos -> pos + size_init_data_list id <= sz0 ->
- contentmap_inject (contents_init_data pos id) (contents_init_data pos id) 0 sz0 0).
- induction id; simpl; intros.
- red; intros; constructor.
- assert (forall n dt,
- size_init_data a = 1 + Z_of_nat n ->
- content_inject dt dt ->
- contentmap_inject (setN n pos dt (contents_init_data (pos + size_init_data a) id))
- (setN n pos dt (contents_init_data (pos + size_init_data a) id))
- 0 sz0 0).
- intros. set (pos' := pos) in |- * at 3. replace pos' with (pos + 0).
- apply setN_inject. apply IHid. omega. omega. auto. auto.
- generalize (size_init_data_list_pos id). omega. unfold pos'; omega.
- destruct a;
- try (apply H1; [reflexivity|repeat constructor]).
- apply IHid. generalize (Zmax2 z 0). omega. simpl in H0; omega.
- apply IHid. omega. simpl size_init_data in H0. omega.
- apply H. omega. unfold sz0. omega.
-Qed.
-
-End MEM_INJECT.
-
-Hint Resolve val_inject_int val_inject_float val_inject_ptr val_inject_undef.
-Hint Resolve val_nil_inject val_cons_inject.
+ mem_inject f m1 m2 ->
+ mem_inject f (free_list m1 l) (free m2 b).
+Proof.
+ intros. inversion H0. constructor.
+ (* inj *)
+ apply free_right_inj. apply free_list_left_inj. auto.
+ intros; red; intros.
+ elim (valid_access_free_list_inv _ _ _ _ _ H2); intros.
+ elim H3; eauto.
+ (* freeblocks *)
+ intros. apply mi_freeblocks0. red; intro; elim H1.
+ apply valid_block_free_list_1; auto.
+ (* mappedblocks *)
+ intros. apply valid_block_free_1. eauto.
+ (* overlap *)
+ apply meminj_no_overlap_free_list; auto.
+ (* range *)
+ auto.
+ intros. destruct (eq_block b' b). subst b'.
+ rewrite low_bound_free_same; rewrite high_bound_free_same.
+ right; compute; intuition congruence.
+ rewrite low_bound_free; auto. rewrite high_bound_free; auto.
+ eauto.
+Qed.
(** Monotonicity properties of memory injections. *)
@@ -2160,16 +2100,11 @@ Lemma inject_incr_refl :
Proof. unfold inject_incr . intros. left . auto . Qed.
Lemma inject_incr_trans :
- forall f1 f2 f3 ,
+ forall f1 f2 f3,
inject_incr f1 f2 -> inject_incr f2 f3 -> inject_incr f1 f3 .
Proof .
- unfold inject_incr . intros .
- generalize (H b) . intro . generalize (H0 b) . intro .
- elim H1 ; elim H2 ; intros.
- rewrite H3 in H4 . left . auto .
- rewrite H3 in H4 . right . auto .
- right ; auto .
- right ; auto .
+ unfold inject_incr; intros.
+ generalize (H b); generalize (H0 b); intuition congruence.
Qed.
Lemma val_inject_incr:
@@ -2192,61 +2127,17 @@ Lemma val_list_inject_incr:
inject_incr f1 f2 -> val_list_inject f1 vl vl' ->
val_list_inject f2 vl vl'.
Proof.
- induction vl ; intros; inversion H0. auto .
- subst a . generalize (val_inject_incr f1 f2 v v' H H3) .
- intro . auto .
-Qed.
-
-Hint Resolve inject_incr_refl val_inject_incr val_list_inject_incr.
-
-Section MEM_INJECT_INCR.
-
-Variable f1 f2: meminj.
-Hypothesis INCR: inject_incr f1 f2.
-
-Lemma val_content_inject_incr:
- forall chunk v v',
- val_content_inject f1 chunk v v' ->
- val_content_inject f2 chunk v v'.
-Proof.
- intros. inversion H.
- apply val_content_inject_base. eapply val_inject_incr; eauto.
- apply val_content_inject_8; auto.
- apply val_content_inject_16; auto.
- apply val_content_inject_32; auto.
+ induction vl; intros; inv H0. auto.
+ constructor. eapply val_inject_incr; eauto. auto.
Qed.
-Lemma content_inject_incr:
- forall c c', content_inject f1 c c' -> content_inject f2 c c'.
-Proof.
- induction 1; constructor; eapply val_content_inject_incr; eauto.
-Qed.
-
-Lemma contentmap_inject_incr:
- forall c c' lo hi delta,
- contentmap_inject f1 c c' lo hi delta ->
- contentmap_inject f2 c c' lo hi delta.
-Proof.
- unfold contentmap_inject; intros.
- apply content_inject_incr. auto.
-Qed.
-
-Lemma block_contents_inject_incr:
- forall c c' delta,
- block_contents_inject f1 c c' delta ->
- block_contents_inject f2 c c' delta.
-Proof.
- intros. inversion H. constructor; auto.
- apply contentmap_inject_incr; auto.
-Qed.
-
-End MEM_INJECT_INCR.
+Hint Resolve inject_incr_refl val_inject_incr val_list_inject_incr.
(** Properties of injections and allocations. *)
Definition extend_inject
(b: block) (x: option (block * Z)) (f: meminj) : meminj :=
- fun b' => if eq_block b' b then x else f b'.
+ fun (b': block) => if zeq b' b then x else f b'.
Lemma extend_inject_incr:
forall f b x,
@@ -2254,7 +2145,7 @@ Lemma extend_inject_incr:
inject_incr f (extend_inject b x f).
Proof.
intros; red; intros. unfold extend_inject.
- case (eq_block b0 b); intro. subst b0. right; auto. left; auto.
+ destruct (zeq b0 b). subst b0; auto. auto.
Qed.
Lemma alloc_right_inject:
@@ -2263,14 +2154,17 @@ Lemma alloc_right_inject:
alloc m2 lo hi = (m2', b) ->
mem_inject f m1 m2'.
Proof.
- intros. unfold alloc in H0. injection H0; intros A B; clear H0.
- inversion H.
- constructor.
- assumption.
- intros. generalize (mi_mappedblocks0 _ _ _ H0). intros [C D].
- rewrite <- B; simpl. split. omega.
- rewrite update_o. auto. omega.
- assumption.
+ intros. inversion H. constructor.
+ eapply alloc_right_inj; eauto.
+ auto.
+ intros. eauto with mem.
+ auto.
+ auto.
+ intros. replace (low_bound m2' b') with (low_bound m2 b').
+ replace (high_bound m2' b') with (high_bound m2 b').
+ eauto.
+ symmetry. eapply high_bound_alloc_other; eauto.
+ symmetry. eapply low_bound_alloc_other; eauto.
Qed.
Lemma alloc_unmapped_inject:
@@ -2280,26 +2174,36 @@ Lemma alloc_unmapped_inject:
mem_inject (extend_inject b None f) m1' m2 /\
inject_incr f (extend_inject b None f).
Proof.
- intros. unfold alloc in H0. injection H0; intros; clear H0.
- inversion H.
+ intros. inversion H.
assert (inject_incr f (extend_inject b None f)).
- apply extend_inject_incr. apply mi_freeblocks0. rewrite H1. omega.
- split; auto.
- constructor.
- rewrite <- H2; simpl; intros. unfold extend_inject.
- case (eq_block b0 b); intro. auto. apply mi_freeblocks0. omega.
- intros until delta. unfold extend_inject at 1. case (eq_block b0 b); intro.
- intros; discriminate.
- intros. rewrite <- H2; simpl. rewrite H1.
- rewrite update_o; auto.
- elim (mi_mappedblocks0 _ _ _ H3). intros A B.
- split. auto. apply block_contents_inject_incr with f. auto. auto.
- intros until delta2. unfold extend_inject.
- case (eq_block b1 b); intro. congruence.
- case (eq_block b2 b); intro. congruence.
- rewrite <- H2. unfold low_bound, high_bound; simpl. rewrite H1.
- repeat rewrite update_o; auto.
- exact (mi_no_overlap0 b1 b2 b1' b2' delta1 delta2).
+ apply extend_inject_incr. apply mi_freeblocks0. eauto with mem.
+ split; auto. constructor.
+ (* inj *)
+ eapply alloc_left_unmapped_inj; eauto.
+ red; intros. unfold extend_inject in H2.
+ destruct (zeq b1 b). congruence.
+ exploit mi_inj0; eauto. intros [v2 [LOAD VINJ]].
+ exists v2; split. auto.
+ apply val_inject_incr with f; auto.
+ unfold extend_inject. apply zeq_true.
+ (* freeblocks *)
+ intros. unfold extend_inject. destruct (zeq b0 b). auto.
+ apply mi_freeblocks0; red; intro. elim H2. eauto with mem.
+ (* mappedblocks *)
+ intros. unfold extend_inject in H2. destruct (zeq b0 b).
+ discriminate. eauto.
+ (* overlap *)
+ red; unfold extend_inject, update; intros.
+ repeat rewrite (low_bound_alloc _ _ _ _ _ H0).
+ repeat rewrite (high_bound_alloc _ _ _ _ _ H0).
+ destruct (zeq b1 b); try discriminate.
+ destruct (zeq b2 b); try discriminate.
+ eauto.
+ (* range *)
+ unfold extend_inject; intros.
+ destruct (zeq b0 b). discriminate. eauto.
+ unfold extend_inject; intros.
+ destruct (zeq b0 b). discriminate. eauto.
Qed.
Lemma alloc_mapped_inject:
@@ -2319,50 +2223,41 @@ Lemma alloc_mapped_inject:
mem_inject (extend_inject b (Some (b', ofs)) f) m1' m2 /\
inject_incr f (extend_inject b (Some (b', ofs)) f).
Proof.
- intros.
- generalize (fun b' => low_bound_alloc _ _ b' _ _ _ H0).
- intro LOW.
- generalize (fun b' => high_bound_alloc _ _ b' _ _ _ H0).
- intro HIGH.
- unfold alloc in H0. injection H0; intros A B; clear H0.
- inversion H.
- (* inject_incr *)
+ intros. inversion H.
assert (inject_incr f (extend_inject b (Some (b', ofs)) f)).
- apply extend_inject_incr. apply mi_freeblocks0. rewrite A. omega.
+ apply extend_inject_incr. apply mi_freeblocks0. eauto with mem.
split; auto.
constructor.
- (* mi_freeblocks *)
- rewrite <- B; simpl; intros. unfold extend_inject.
- case (eq_block b0 b); intro. unfold block in *. omegaContradiction.
- apply mi_freeblocks0. omega.
- (* mi_mappedblocks *)
- intros until delta. unfold extend_inject at 1.
- case (eq_block b0 b); intro.
- intros. subst b0. inversion H8. subst b'0; subst delta.
- split. assumption.
- rewrite <- B; simpl. rewrite A. rewrite update_s.
- constructor; auto.
- unfold empty_block. simpl. intros. unfold low_bound in H5. unfold high_bound in H6. omega.
- simpl. red; intros. constructor.
- intros.
- generalize (mi_mappedblocks0 _ _ _ H8). intros [C D].
- split. auto.
- rewrite <- B; simpl; rewrite A; rewrite update_o; auto.
- apply block_contents_inject_incr with f; auto.
- (* no overlap *)
- intros until delta2. unfold extend_inject.
- repeat rewrite LOW. repeat rewrite HIGH. unfold eq_block.
- case (zeq b1 b); case (zeq b2 b); intros.
- congruence.
- inversion H9. subst b1'; subst delta1.
- case (eq_block b' b2'); intro.
- subst b2'. generalize (H7 _ _ H10). intro.
- right. intros. omega. left. auto.
- inversion H10. subst b2'; subst delta2.
- case (eq_block b' b1'); intro.
- subst b1'. generalize (H7 _ _ H9). intro.
- right. intros. omega. left. auto.
- apply mi_no_overlap0; auto.
+ (* inj *)
+ eapply alloc_left_mapped_inj; eauto.
+ red; intros. unfold extend_inject in H9.
+ rewrite zeq_false in H9.
+ exploit mi_inj0; eauto. intros [v2 [LOAD VINJ]].
+ exists v2; split. auto. eapply val_inject_incr; eauto.
+ eauto with mem.
+ unfold extend_inject. apply zeq_true.
+ (* freeblocks *)
+ intros. unfold extend_inject. rewrite zeq_false.
+ apply mi_freeblocks0. red; intro. elim H9; eauto with mem.
+ apply sym_not_equal; eauto with mem.
+ (* mappedblocks *)
+ unfold extend_inject; intros.
+ destruct (zeq b0 b). inv H9. auto. eauto.
+ (* overlap *)
+ red; unfold extend_inject, update; intros.
+ repeat rewrite (low_bound_alloc _ _ _ _ _ H0).
+ repeat rewrite (high_bound_alloc _ _ _ _ _ H0).
+ destruct (zeq b1 b); [inv H10|idtac];
+ (destruct (zeq b2 b); [inv H11|idtac]).
+ congruence.
+ destruct (zeq b1' b2'). subst b2'. generalize (H7 _ _ H11). tauto. auto.
+ destruct (zeq b1' b2'). subst b2'. generalize (H7 _ _ H10). tauto. auto.
+ eauto.
+ (* range *)
+ unfold extend_inject; intros.
+ destruct (zeq b0 b). inv H9. auto. eauto.
+ unfold extend_inject; intros.
+ destruct (zeq b0 b). inv H9. auto. eauto.
Qed.
Lemma alloc_parallel_inject:
@@ -2371,20 +2266,104 @@ Lemma alloc_parallel_inject:
alloc m1 lo hi = (m1', b1) ->
alloc m2 lo hi = (m2', b2) ->
Int.min_signed <= lo -> hi <= Int.max_signed ->
- mem_inject (extend_inject b1 (Some(b2,0)) f) m1' m2' /\
- inject_incr f (extend_inject b1 (Some(b2,0)) f).
+ mem_inject (extend_inject b1 (Some(b2, 0)) f) m1' m2' /\
+ inject_incr f (extend_inject b1 (Some(b2, 0)) f).
Proof.
intros.
- generalize (low_bound_alloc _ _ b2 _ _ _ H1). rewrite zeq_true; intro LOW.
- generalize (high_bound_alloc _ _ b2 _ _ _ H1). rewrite zeq_true; intro HIGH.
eapply alloc_mapped_inject; eauto.
eapply alloc_right_inject; eauto.
- eapply valid_new_block; eauto.
- compute. intuition congruence.
- rewrite LOW; auto.
- rewrite HIGH; auto.
- rewrite LOW; omega.
- rewrite HIGH; omega.
- intros. elim (mi_mappedblocks _ _ _ H _ _ _ H4); intros.
- injection H1; intros. rewrite H7 in H5. omegaContradiction.
+ eauto with mem.
+ compute; intuition congruence.
+ rewrite (low_bound_alloc_same _ _ _ _ _ H1). auto.
+ rewrite (high_bound_alloc_same _ _ _ _ _ H1). auto.
+ rewrite (low_bound_alloc_same _ _ _ _ _ H1). omega.
+ rewrite (high_bound_alloc_same _ _ _ _ _ H1). omega.
+ intros. elimtype False. inv H.
+ exploit mi_mappedblocks0; eauto.
+ change (~ valid_block m2 b2). eauto with mem.
+Qed.
+
+Definition meminj_init (m: mem) : meminj :=
+ fun (b: block) => if zlt b m.(nextblock) then Some(b, 0) else None.
+
+Definition mem_inject_neutral (m: mem) : Prop :=
+ forall f chunk b ofs v,
+ load chunk m b ofs = Some v -> val_inject f v v.
+
+Lemma init_inject:
+ forall m,
+ mem_inject_neutral m ->
+ mem_inject (meminj_init m) m m.
+Proof.
+ intros; constructor.
+ (* inj *)
+ red; intros. unfold meminj_init in H0.
+ destruct (zlt b1 (nextblock m)); inversion H0.
+ subst b2 delta. exists v1; split.
+ rewrite Zplus_0_r. auto. eapply H; eauto.
+ (* free blocks *)
+ unfold valid_block, meminj_init; intros.
+ apply zlt_false. omega.
+ (* mapped blocks *)
+ unfold valid_block, meminj_init; intros.
+ destruct (zlt b (nextblock m)); inversion H0. subst b'; auto.
+ (* overlap *)
+ red; unfold meminj_init; intros.
+ destruct (zlt b1 (nextblock m)); inversion H1.
+ destruct (zlt b2 (nextblock m)); inversion H2.
+ left; congruence.
+ (* range *)
+ unfold meminj_init; intros.
+ destruct (zlt b (nextblock m)); inversion H0. subst delta.
+ compute; intuition congruence.
+ unfold meminj_init; intros.
+ destruct (zlt b (nextblock m)); inversion H0. subst delta.
+ auto.
+Qed.
+
+Remark getN_setN_inject:
+ forall f m v n1 p1 n2 p2,
+ val_inject f (getN n2 p2 m) (getN n2 p2 m) ->
+ val_inject f v v ->
+ val_inject f (getN n2 p2 (setN n1 p1 v m))
+ (getN n2 p2 (setN n1 p1 v m)).
+Proof.
+ intros.
+ destruct (getN_setN_characterization m v n1 p1 n2 p2)
+ as [A | [A | A]]; rewrite A; auto.
+Qed.
+
+Remark getN_contents_init_data_inject:
+ forall f n ofs id pos,
+ val_inject f (getN n ofs (contents_init_data pos id))
+ (getN n ofs (contents_init_data pos id)).
+Proof.
+ induction id; simpl; intros.
+ repeat rewrite getN_init. constructor.
+ destruct a; auto; apply getN_setN_inject; auto.
+Qed.
+
+Lemma alloc_init_data_neutral:
+ forall m id m' b,
+ mem_inject_neutral m ->
+ alloc_init_data m id = (m', b) ->
+ mem_inject_neutral m'.
+Proof.
+ intros. injection H0; intros A B.
+ red; intros.
+ exploit load_inv; eauto. intros [C D].
+ rewrite <- B in D; simpl in D. rewrite A in D.
+ unfold update in D. destruct (zeq b0 b).
+ subst b0. rewrite D. simpl.
+ apply load_result_inject with chunk. constructor.
+ apply getN_contents_init_data_inject. auto.
+ apply H with chunk b0 ofs. unfold load.
+ rewrite in_bounds_true. congruence.
+ inversion C. constructor.
+ generalize H2. unfold valid_block. rewrite <- B; simpl.
+ rewrite A. unfold block in n; intros. omega.
+ replace (low_bound m b0) with (low_bound m' b0). auto.
+ unfold low_bound; rewrite <- B; simpl; rewrite A. rewrite update_o; auto.
+ replace (high_bound m b0) with (high_bound m' b0). auto.
+ unfold high_bound; rewrite <- B; simpl; rewrite A. rewrite update_o; auto.
Qed.
diff --git a/common/Smallstep.v b/common/Smallstep.v
new file mode 100644
index 0000000..7f6c776
--- /dev/null
+++ b/common/Smallstep.v
@@ -0,0 +1,460 @@
+(** Tools for small-step operational semantics *)
+
+(** This module defines generic operations and theorems over
+ the one-step transition relations that are used to specify
+ operational semantics in small-step style. *)
+
+Require Import Coqlib.
+Require Import AST.
+Require Import Events.
+Require Import Globalenvs.
+Require Import Integers.
+
+Set Implicit Arguments.
+
+(** * Closures of transitions relations *)
+
+Section CLOSURES.
+
+Variable genv: Set.
+Variable state: Set.
+
+(** A one-step transition relation has the following signature.
+ It is parameterized by a global environment, which does not
+ change during the transition. It relates the initial state
+ of the transition with its final state. The [trace] parameter
+ captures the observable events possibly generated during the
+ transition. *)
+
+Variable step: genv -> state -> trace -> state -> Prop.
+
+(** Zero, one or several transitions. Also known as Kleene closure,
+ or reflexive transitive closure. *)
+
+Inductive star (ge: genv): state -> trace -> state -> Prop :=
+ | star_refl: forall s,
+ star ge s E0 s
+ | star_step: forall s1 t1 s2 t2 s3 t,
+ step ge s1 t1 s2 -> star ge s2 t2 s3 -> t = t1 ** t2 ->
+ star ge s1 t s3.
+
+Lemma star_one:
+ forall ge s1 t s2, step ge s1 t s2 -> star ge s1 t s2.
+Proof.
+ intros. eapply star_step; eauto. apply star_refl. traceEq.
+Qed.
+
+Lemma star_trans:
+ forall ge s1 t1 s2, star ge s1 t1 s2 ->
+ forall t2 s3 t, star ge s2 t2 s3 -> t = t1 ** t2 -> star ge s1 t s3.
+Proof.
+ induction 1; intros.
+ rewrite H0. simpl. auto.
+ eapply star_step; eauto. traceEq.
+Qed.
+
+Lemma star_left:
+ forall ge s1 t1 s2 t2 s3 t,
+ step ge s1 t1 s2 -> star ge s2 t2 s3 -> t = t1 ** t2 ->
+ star ge s1 t s3.
+Proof star_step.
+
+Lemma star_right:
+ forall ge s1 t1 s2 t2 s3 t,
+ star ge s1 t1 s2 -> step ge s2 t2 s3 -> t = t1 ** t2 ->
+ star ge s1 t s3.
+Proof.
+ intros. eapply star_trans. eauto. apply star_one. eauto. auto.
+Qed.
+
+(** One or several transitions. Also known as the transitive closure. *)
+
+Inductive plus (ge: genv): state -> trace -> state -> Prop :=
+ | plus_left: forall s1 t1 s2 t2 s3 t,
+ step ge s1 t1 s2 -> star ge s2 t2 s3 -> t = t1 ** t2 ->
+ plus ge s1 t s3.
+
+Lemma plus_one:
+ forall ge s1 t s2,
+ step ge s1 t s2 -> plus ge s1 t s2.
+Proof.
+ intros. econstructor; eauto. apply star_refl. traceEq.
+Qed.
+
+Lemma plus_star:
+ forall ge s1 t s2, plus ge s1 t s2 -> star ge s1 t s2.
+Proof.
+ intros. inversion H; subst.
+ eapply star_step; eauto.
+Qed.
+
+Lemma plus_right:
+ forall ge s1 t1 s2 t2 s3 t,
+ star ge s1 t1 s2 -> step ge s2 t2 s3 -> t = t1 ** t2 ->
+ plus ge s1 t s3.
+Proof.
+ intros. inversion H; subst. simpl. apply plus_one. auto.
+ rewrite Eapp_assoc. eapply plus_left; eauto.
+ eapply star_right; eauto.
+Qed.
+
+Lemma plus_left':
+ forall ge s1 t1 s2 t2 s3 t,
+ step ge s1 t1 s2 -> plus ge s2 t2 s3 -> t = t1 ** t2 ->
+ plus ge s1 t s3.
+Proof.
+ intros. eapply plus_left; eauto. apply plus_star; auto.
+Qed.
+
+Lemma plus_right':
+ forall ge s1 t1 s2 t2 s3 t,
+ plus ge s1 t1 s2 -> step ge s2 t2 s3 -> t = t1 ** t2 ->
+ plus ge s1 t s3.
+Proof.
+ intros. eapply plus_right; eauto. apply plus_star; auto.
+Qed.
+
+Lemma plus_star_trans:
+ forall ge s1 t1 s2 t2 s3 t,
+ plus ge s1 t1 s2 -> star ge s2 t2 s3 -> t = t1 ** t2 -> plus ge s1 t s3.
+Proof.
+ intros. inversion H; subst.
+ econstructor; eauto. eapply star_trans; eauto.
+ traceEq.
+Qed.
+
+Lemma star_plus_trans:
+ forall ge s1 t1 s2 t2 s3 t,
+ star ge s1 t1 s2 -> plus ge s2 t2 s3 -> t = t1 ** t2 -> plus ge s1 t s3.
+Proof.
+ intros. inversion H; subst.
+ simpl; auto.
+ rewrite Eapp_assoc.
+ econstructor. eauto. eapply star_trans. eauto.
+ apply plus_star. eauto. eauto. auto.
+Qed.
+
+Lemma plus_trans:
+ forall ge s1 t1 s2 t2 s3 t,
+ plus ge s1 t1 s2 -> plus ge s2 t2 s3 -> t = t1 ** t2 -> plus ge s1 t s3.
+Proof.
+ intros. eapply plus_star_trans. eauto. apply plus_star. eauto. auto.
+Qed.
+
+Lemma plus_inv:
+ forall ge s1 t s2, plus ge s1 t s2 ->
+ step ge s1 t s2 \/ exists s', exists t1, exists t2, step ge s1 t1 s' /\ plus ge s' t2 s2 /\ t = t1 ** t2.
+Proof.
+ intros. inversion H; subst. inversion H1; subst.
+ left. rewrite E0_right. auto.
+ right. exists s3; exists t1; exists (t0 ** t3); split. auto.
+ split. econstructor; eauto. auto.
+Qed.
+
+(** Infinitely many transitions *)
+
+CoInductive forever (ge: genv): state -> traceinf -> Prop :=
+ | forever_intro: forall s1 t s2 T,
+ step ge s1 t s2 -> forever ge s2 T ->
+ forever ge s1 (t *** T).
+
+(** An alternate, equivalent definition of [forever] that is useful
+ for coinductive reasoning. *)
+
+CoInductive forever_N (ge: genv): nat -> state -> traceinf -> Prop :=
+ | forever_N_star: forall s1 t s2 p q T,
+ star ge s1 t s2 -> (p < q)%nat -> forever_N ge p s2 T ->
+ forever_N ge q s1 (t *** T)
+ | forever_N_plus: forall s1 t s2 p q T,
+ plus ge s1 t s2 -> forever_N ge p s2 T ->
+ forever_N ge q s1 (t *** T).
+
+Remark Peano_induction:
+ forall (P: nat -> Prop),
+ (forall p, (forall q, (q < p)%nat -> P q) -> P p) ->
+ forall p, P p.
+Proof.
+ intros P IH.
+ assert (forall p, forall q, (q < p)%nat -> P q).
+ induction p; intros. elimtype False; omega.
+ apply IH. intros. apply IHp. omega.
+ intro. apply H with (S p). omega.
+Qed.
+
+Lemma forever_N_inv:
+ forall ge p s T,
+ forever_N ge p s T ->
+ exists t, exists s', exists q, exists T',
+ step ge s t s' /\ forever_N ge q s' T' /\ T = t *** T'.
+Proof.
+ intros ge p. pattern p. apply Peano_induction; intros.
+ inv H0.
+ (* star case *)
+ inv H1.
+ (* no transition *)
+ change (E0 *** T0) with T0. apply H with p1. auto. auto.
+ (* at least one transition *)
+ exists t1; exists s0; exists p0; exists (t2 *** T0).
+ split. auto. split. eapply forever_N_star; eauto.
+ apply Eappinf_assoc.
+ (* plus case *)
+ inv H1.
+ exists t1; exists s0; exists (S p1); exists (t2 *** T0).
+ split. auto. split. eapply forever_N_star; eauto.
+ apply Eappinf_assoc.
+Qed.
+
+Lemma forever_N_forever:
+ forall ge p s T, forever_N ge p s T -> forever ge s T.
+Proof.
+ cofix COINDHYP; intros.
+ destruct (forever_N_inv H) as [t [s' [q [T' [A [B C]]]]]].
+ rewrite C. apply forever_intro with s'. auto.
+ apply COINDHYP with q; auto.
+Qed.
+
+(** * Outcomes for program executions *)
+
+(** The two valid outcomes for the execution of a program:
+- Termination, with a finite trace of observable events
+ and an integer value that stands for the process exit code
+ (the return value of the main function).
+- Divergence with an infinite trace of observable events.
+ (The actual events generated by the execution can be a
+ finite prefix of this trace, or the whole trace.)
+*)
+
+Inductive program_behavior: Set :=
+ | Terminates: trace -> int -> program_behavior
+ | Diverges: traceinf -> program_behavior.
+
+(** Given a characterization of initial states and final states,
+ [program_behaves] relates a program behaviour with the
+ sequences of transitions that can be taken from an initial state
+ to a final state. *)
+
+Variable initial_state: state -> Prop.
+Variable final_state: state -> int -> Prop.
+
+Inductive program_behaves (ge: genv): program_behavior -> Prop :=
+ | program_terminates: forall s t s' r,
+ initial_state s ->
+ star ge s t s' ->
+ final_state s' r ->
+ program_behaves ge (Terminates t r)
+ | program_diverges: forall s T,
+ initial_state s ->
+ forever ge s T ->
+ program_behaves ge (Diverges T).
+
+End CLOSURES.
+
+(** * Simulations between two small-step semantics. *)
+
+(** In this section, we show that if two transition relations
+ satisfy certain simulation diagrams, then every program behaviour
+ generated by the first transition relation can also occur
+ with the second transition relation. *)
+
+Section SIMULATION.
+
+(** The first small-step semantics is axiomatized as follows. *)
+
+Variable genv1: Set.
+Variable state1: Set.
+Variable step1: genv1 -> state1 -> trace -> state1 -> Prop.
+Variable initial_state1: state1 -> Prop.
+Variable final_state1: state1 -> int -> Prop.
+Variable ge1: genv1.
+
+(** The second small-step semantics is also axiomatized. *)
+
+Variable genv2: Set.
+Variable state2: Set.
+Variable step2: genv2 -> state2 -> trace -> state2 -> Prop.
+Variable initial_state2: state2 -> Prop.
+Variable final_state2: state2 -> int -> Prop.
+Variable ge2: genv2.
+
+(** We assume given a matching relation between states of both semantics.
+ This matching relation must be compatible with initial states
+ and with final states. *)
+
+
+Variable match_states: state1 -> state2 -> Prop.
+
+Hypothesis match_initial_states:
+ forall st1, initial_state1 st1 ->
+ exists st2, initial_state2 st2 /\ match_states st1 st2.
+
+Hypothesis match_final_states:
+ forall st1 st2 r,
+ match_states st1 st2 ->
+ final_state1 st1 r ->
+ final_state2 st2 r.
+
+(** Simulation when one transition in the first program
+ corresponds to zero, one or several transitions in the second program.
+ However, there is no stuttering: infinitely many transitions
+ in the source program must correspond to infinitely many
+ transitions in the second program. *)
+
+Section SIMULATION_STAR.
+
+(** [measure] is a nonnegative integer associated with states
+ of the first semantics. It must decrease when we take
+ a stuttering step. *)
+
+Variable measure: state1 -> nat.
+
+Hypothesis simulation:
+ forall st1 t st1', step1 ge1 st1 t st1' ->
+ forall st2, match_states st1 st2 ->
+ (exists st2', plus step2 ge2 st2 t st2' /\ match_states st1' st2')
+ \/ (measure st1' < measure st1 /\ t = E0 /\ match_states st1' st2)%nat.
+
+Lemma simulation_star_star:
+ forall st1 t st1', star step1 ge1 st1 t st1' ->
+ forall st2, match_states st1 st2 ->
+ exists st2', star step2 ge2 st2 t st2' /\ match_states st1' st2'.
+Proof.
+ induction 1; intros.
+ exists st2; split. apply star_refl. auto.
+ elim (simulation H H2).
+ intros [st2' [A B]].
+ destruct (IHstar _ B) as [st3' [C D]].
+ exists st3'; split. apply star_trans with t1 st2' t2.
+ apply plus_star; auto. auto. auto. auto.
+ intros [A [B C]]. rewrite H1. rewrite B. simpl. apply IHstar; auto.
+Qed.
+
+Lemma simulation_star_forever:
+ forall st1 st2 T,
+ forever step1 ge1 st1 T -> match_states st1 st2 ->
+ forever step2 ge2 st2 T.
+Proof.
+ assert (forall st1 st2 T,
+ forever step1 ge1 st1 T -> match_states st1 st2 ->
+ forever_N step2 ge2 (measure st1) st2 T).
+ cofix COINDHYP; intros.
+ inversion H; subst. elim (simulation H1 H0).
+ intros [st2' [A B]]. apply forever_N_plus with st2' (measure s2).
+ auto. apply COINDHYP. assumption. assumption.
+ intros [A [B C]].
+ apply forever_N_star with st2 (measure s2).
+ rewrite B. apply star_refl. auto.
+ apply COINDHYP. assumption. auto.
+ intros. eapply forever_N_forever; eauto.
+Qed.
+
+Lemma simulation_star_preservation:
+ forall beh,
+ program_behaves step1 initial_state1 final_state1 ge1 beh ->
+ program_behaves step2 initial_state2 final_state2 ge2 beh.
+Proof.
+ intros. inversion H; subst.
+ destruct (match_initial_states H0) as [s2 [A B]].
+ destruct (simulation_star_star H1 B) as [s2' [C D]].
+ econstructor; eauto.
+ destruct (match_initial_states H0) as [s2 [A B]].
+ econstructor; eauto.
+ eapply simulation_star_forever; eauto.
+Qed.
+
+End SIMULATION_STAR.
+
+(** Lock-step simulation: each transition in the first semantics
+ corresponds to exactly one transition in the second semantics. *)
+
+Section SIMULATION_STEP.
+
+Hypothesis simulation:
+ forall st1 t st1', step1 ge1 st1 t st1' ->
+ forall st2, match_states st1 st2 ->
+ exists st2', step2 ge2 st2 t st2' /\ match_states st1' st2'.
+
+Lemma simulation_step_preservation:
+ forall beh,
+ program_behaves step1 initial_state1 final_state1 ge1 beh ->
+ program_behaves step2 initial_state2 final_state2 ge2 beh.
+Proof.
+ intros.
+ pose (measure := fun (st: state1) => 0%nat).
+ assert (simulation':
+ forall st1 t st1', step1 ge1 st1 t st1' ->
+ forall st2, match_states st1 st2 ->
+ (exists st2', plus step2 ge2 st2 t st2' /\ match_states st1' st2')
+ \/ (measure st1' < measure st1 /\ t = E0 /\ match_states st1' st2)%nat).
+ intros. destruct (simulation H0 H1) as [st2' [A B]].
+ left; exists st2'; split. apply plus_one; auto. auto.
+ eapply simulation_star_preservation; eauto.
+Qed.
+
+End SIMULATION_STEP.
+
+(** Simulation when one transition in the first program corresponds
+ to one or several transitions in the second program. *)
+
+Section SIMULATION_PLUS.
+
+Hypothesis simulation:
+ forall st1 t st1', step1 ge1 st1 t st1' ->
+ forall st2, match_states st1 st2 ->
+ exists st2', plus step2 ge2 st2 t st2' /\ match_states st1' st2'.
+
+Lemma simulation_plus_preservation:
+ forall beh,
+ program_behaves step1 initial_state1 final_state1 ge1 beh ->
+ program_behaves step2 initial_state2 final_state2 ge2 beh.
+Proof.
+ intros.
+ pose (measure := fun (st: state1) => 0%nat).
+ assert (simulation':
+ forall st1 t st1', step1 ge1 st1 t st1' ->
+ forall st2, match_states st1 st2 ->
+ (exists st2', plus step2 ge2 st2 t st2' /\ match_states st1' st2')
+ \/ (measure st1' < measure st1 /\ t = E0 /\ match_states st1' st2)%nat).
+ intros. destruct (simulation H0 H1) as [st2' [A B]].
+ left; exists st2'; auto.
+ eapply simulation_star_preservation; eauto.
+Qed.
+
+End SIMULATION_PLUS.
+
+(** Simulation when one transition in the first program
+ corresponds to zero or one transitions in the second program.
+ However, there is no stuttering: infinitely many transitions
+ in the source program must correspond to infinitely many
+ transitions in the second program. *)
+
+Section SIMULATION_OPT.
+
+Variable measure: state1 -> nat.
+
+Hypothesis simulation:
+ forall st1 t st1', step1 ge1 st1 t st1' ->
+ forall st2, match_states st1 st2 ->
+ (exists st2', step2 ge2 st2 t st2' /\ match_states st1' st2')
+ \/ (measure st1' < measure st1 /\ t = E0 /\ match_states st1' st2)%nat.
+
+Lemma simulation_opt_preservation:
+ forall beh,
+ program_behaves step1 initial_state1 final_state1 ge1 beh ->
+ program_behaves step2 initial_state2 final_state2 ge2 beh.
+Proof.
+ assert (simulation':
+ forall st1 t st1', step1 ge1 st1 t st1' ->
+ forall st2, match_states st1 st2 ->
+ (exists st2', plus step2 ge2 st2 t st2' /\ match_states st1' st2')
+ \/ (measure st1' < measure st1 /\ t = E0 /\ match_states st1' st2)%nat).
+ intros. elim (simulation H H0).
+ intros [st2' [A B]]. left. exists st2'; split. apply plus_one; auto. auto.
+ intros [A [B C]]. right. intuition.
+ intros. eapply simulation_star_preservation; eauto.
+Qed.
+
+End SIMULATION_OPT.
+
+End SIMULATION.
+
+
diff --git a/common/Switch.v b/common/Switch.v
new file mode 100644
index 0000000..e8b3967
--- /dev/null
+++ b/common/Switch.v
@@ -0,0 +1,165 @@
+(** Multi-way branches (``[switch]'') and their compilation
+ to 2-way comparison trees. *)
+
+Require Import EqNat.
+Require Import Coqlib.
+Require Import Integers.
+
+(** A multi-way branch is composed of a list of (key, action) pairs,
+ plus a default action. *)
+
+Definition table : Set := list (int * nat).
+
+Fixpoint switch_target (n: int) (dfl: nat) (cases: table)
+ {struct cases} : nat :=
+ match cases with
+ | nil => dfl
+ | (key, action) :: rem =>
+ if Int.eq n key then action else switch_target n dfl rem
+ end.
+
+(** Multi-way branches are translated to a 2-way comparison tree.
+ Each node of the tree performs an equality test or a less-than
+ test against one of the keys. *)
+
+Inductive comptree : Set :=
+ | CTaction: nat -> comptree
+ | CTifeq: int -> nat -> comptree -> comptree
+ | CTiflt: int -> comptree -> comptree -> comptree.
+
+Fixpoint comptree_match (n: int) (t: comptree) {struct t}: nat :=
+ match t with
+ | CTaction act => act
+ | CTifeq key act t' =>
+ if Int.eq n key then act else comptree_match n t'
+ | CTiflt key t1 t2 =>
+ if Int.ltu n key then comptree_match n t1 else comptree_match n t2
+ end.
+
+(** The translation from a table to a comparison tree is performed
+ by untrusted Caml code (function [compile_switch] in
+ file [RTLgenaux.ml]). In Coq, we validate a posteriori the
+ result of this function. In other terms, we now develop
+ and prove correct Coq functions that take a table and a comparison
+ tree, and check that their semantics are equivalent. *)
+
+Fixpoint split_lt (pivot: int) (cases: table)
+ {struct cases} : table * table :=
+ match cases with
+ | nil => (nil, nil)
+ | (key, act) :: rem =>
+ let (l, r) := split_lt pivot rem in
+ if Int.ltu key pivot
+ then ((key, act) :: l, r)
+ else (l, (key, act) :: r)
+ end.
+
+Fixpoint split_eq (pivot: int) (cases: table)
+ {struct cases} : option nat * table :=
+ match cases with
+ | nil => (None, nil)
+ | (key, act) :: rem =>
+ let (same, others) := split_eq pivot rem in
+ if Int.eq key pivot
+ then (Some act, others)
+ else (same, (key, act) :: others)
+ end.
+
+Fixpoint validate_switch (default: nat) (cases: table) (t: comptree)
+ {struct t} : bool :=
+ match t with
+ | CTaction act =>
+ match cases with
+ | nil => beq_nat act default
+ | _ => false
+ end
+ | CTifeq pivot act t' =>
+ match split_eq pivot cases with
+ | (None, _) => false
+ | (Some act', others) => beq_nat act act' && validate_switch default others t'
+ end
+ | CTiflt pivot t1 t2 =>
+ match split_lt pivot cases with
+ | (lcases, rcases) =>
+ validate_switch default lcases t1 && validate_switch default rcases t2
+ end
+ end.
+
+(** Correctness proof for validation. *)
+
+Lemma split_eq_prop:
+ forall v default n cases optact cases',
+ split_eq n cases = (optact, cases') ->
+ switch_target v default cases =
+ (if Int.eq v n
+ then match optact with Some act => act | None => default end
+ else switch_target v default cases').
+Proof.
+ induction cases; simpl; intros until cases'.
+ intros. inversion H; subst. simpl.
+ destruct (Int.eq v n); auto.
+ destruct a as [key act].
+ case_eq (split_eq n cases). intros same other SEQ.
+ rewrite (IHcases _ _ SEQ).
+ predSpec Int.eq Int.eq_spec key n; intro EQ; inversion EQ; simpl.
+ subst n. destruct (Int.eq v key). auto. auto.
+ predSpec Int.eq Int.eq_spec v key.
+ subst v. predSpec Int.eq Int.eq_spec key n. congruence. auto.
+ auto.
+Qed.
+
+Lemma split_lt_prop:
+ forall v default n cases lcases rcases,
+ split_lt n cases = (lcases, rcases) ->
+ switch_target v default cases =
+ (if Int.ltu v n
+ then switch_target v default lcases
+ else switch_target v default rcases).
+Proof.
+ induction cases; intros until rcases; simpl.
+ intro. inversion H; subst. simpl.
+ destruct (Int.ltu v n); auto.
+ destruct a as [key act].
+ case_eq (split_lt n cases). intros lc rc SEQ.
+ rewrite (IHcases _ _ SEQ).
+ case_eq (Int.ltu key n); intros; inv H0; simpl.
+ predSpec Int.eq Int.eq_spec v key.
+ subst v. rewrite H. auto.
+ auto.
+ predSpec Int.eq Int.eq_spec v key.
+ subst v. rewrite H. auto.
+ auto.
+Qed.
+
+Definition table_tree_agree
+ (default: nat) (cases: table) (t: comptree) : Prop :=
+ forall v, switch_target v default cases = comptree_match v t.
+
+Lemma validate_switch_correct:
+ forall default t cases,
+ validate_switch default cases t = true ->
+ table_tree_agree default cases t.
+Proof.
+ induction t; simpl; intros until cases.
+ (* base case *)
+ destruct cases. 2: congruence.
+ intro. replace n with default.
+ red; intros; simpl; auto.
+ symmetry. apply beq_nat_eq. auto.
+ (* eq node *)
+ case_eq (split_eq i cases). intros optact cases' EQ.
+ destruct optact as [ act | ]. 2: congruence.
+ intros. destruct (andb_prop _ _ H).
+ replace n with act.
+ generalize (IHt _ H1); intro.
+ red; intros. simpl. rewrite <- H2.
+ change act with (match Some act with Some act => act | None => default end).
+ eapply split_eq_prop; eauto.
+ symmetry. apply beq_nat_eq. auto.
+ (* lt node *)
+ case_eq (split_lt i cases). intros lcases rcases EQ V.
+ destruct (andb_prop _ _ V).
+ red; intros. simpl.
+ rewrite <- (IHt1 _ H). rewrite <- (IHt2 _ H0).
+ eapply split_lt_prop; eauto.
+Qed.
diff --git a/common/Values.v b/common/Values.v
index aa59e04..e5b4971 100644
--- a/common/Values.v
+++ b/common/Values.v
@@ -885,4 +885,68 @@ Proof.
elim H0; intro; subst v; reflexivity.
Qed.
+(** The ``is less defined'' relation between values.
+ A value is less defined than itself, and [Vundef] is
+ less defined than any value. *)
+
+Inductive lessdef: val -> val -> Prop :=
+ | lessdef_refl: forall v, lessdef v v
+ | lessdef_undef: forall v, lessdef Vundef v.
+
+Inductive lessdef_list: list val -> list val -> Prop :=
+ | lessdef_list_nil:
+ lessdef_list nil nil
+ | lessdef_list_cons:
+ forall v1 v2 vl1 vl2,
+ lessdef v1 v2 -> lessdef_list vl1 vl2 ->
+ lessdef_list (v1 :: vl1) (v2 :: vl2).
+
+Hint Resolve lessdef_refl lessdef_undef lessdef_list_nil lessdef_list_cons.
+
+Lemma lessdef_list_inv:
+ forall vl1 vl2, lessdef_list vl1 vl2 -> vl1 = vl2 \/ In Vundef vl1.
+Proof.
+ induction 1; simpl.
+ tauto.
+ inv H. destruct IHlessdef_list.
+ left; congruence. tauto. tauto.
+Qed.
+
+Lemma load_result_lessdef:
+ forall chunk v1 v2,
+ lessdef v1 v2 -> lessdef (load_result chunk v1) (load_result chunk v2).
+Proof.
+ intros. inv H. auto. destruct chunk; simpl; auto.
+Qed.
+
+Lemma cast8signed_lessdef:
+ forall v1 v2, lessdef v1 v2 -> lessdef (cast8signed v1) (cast8signed v2).
+Proof.
+ intros; inv H; simpl; auto.
+Qed.
+
+Lemma cast8unsigned_lessdef:
+ forall v1 v2, lessdef v1 v2 -> lessdef (cast8unsigned v1) (cast8unsigned v2).
+Proof.
+ intros; inv H; simpl; auto.
+Qed.
+
+Lemma cast16signed_lessdef:
+ forall v1 v2, lessdef v1 v2 -> lessdef (cast16signed v1) (cast16signed v2).
+Proof.
+ intros; inv H; simpl; auto.
+Qed.
+
+Lemma cast16unsigned_lessdef:
+ forall v1 v2, lessdef v1 v2 -> lessdef (cast16unsigned v1) (cast16unsigned v2).
+Proof.
+ intros; inv H; simpl; auto.
+Qed.
+
+Lemma singleoffloat_lessdef:
+ forall v1 v2, lessdef v1 v2 -> lessdef (singleoffloat v1) (singleoffloat v2).
+Proof.
+ intros; inv H; simpl; auto.
+Qed.
+
End Val.
diff --git a/coq b/coq
index 1f6bf5f..b110c54 100755
--- a/coq
+++ b/coq
@@ -1,4 +1,4 @@
#!/bin/sh
# Start coqide with the right -I options
-exec coqide -I lib -I common -I backend -I cfrontend "$@"
+coqide -I lib -I common -I backend -I cfrontend $1 && make ${1}o
diff --git a/doc/backend.html b/doc/backend.html
deleted file mode 100644
index e33896c..0000000
--- a/doc/backend.html
+++ /dev/null
@@ -1,250 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
-<HTML>
-<HEAD>
-<TITLE>The Compcert certified compiler back-end</TITLE>
-<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
-
-<style type="text/css">
-body {
- color: black; background: white;
- margin-left: 5%; margin-right: 5%;
-}
-h2 { margin-left: -5%;}
-h3,h4,h5,h6 { margin-left: -3%; }
-hr { margin-left: -5%; margin-right:-5%; }
-a:visited {color : #416DFF; text-decoration : none; }
-a:link {color : #416DFF; text-decoration : none; font-weight : bold}
-a:hover {color : Red; text-decoration : underline; }
-a:active {color : Red; text-decoration : underline; }
-</style>
-
-<LINK type="text/css" rel="stylesheet" href="style.css">
-</HEAD>
-<BODY>
-
-<H1 align="center">The Compcert certified compiler back-end</H1>
-<H2 align="center">Commented Coq development</H2>
-<H3 align="center">Version 0.2, 2006-01-07</H3>
-
-<H2>Introduction</H2>
-
-<P>The Compcert back-end is a compiler that generates PowerPC assembly
-code from a low-level intermediate language called Cminor and a
-slightly more expressive intermediate language called Csharpminor.
-The particularity of this compiler is that it is written mostly within
-the specification language of the Coq proof assistant, and its
-correctness --- the fact that the generated assembly code is
-semantically equivalent to its source program --- was entirely proved
-within the Coq proof assistant.</P>
-
-<P>A high-level overview of the Compcert back-end and its proof of
-correctness can be found in the following paper:</P>
-<CITE>Xavier Leroy, <A
-HREF="http://pauillac.inria.fr/~xleroy/publi/compiler-certif.pdf">Formal
-certification of a compiler back-end, or: programming a compiler with
-a proof assistant</A>. Proceedings of the POPL 2006 symposium.</CITE>
-
-<P>This Web site gives a commented listing of the underlying Coq
-specifications and proofs. Proof scripts and the parts of the
-compiler written directly in Caml are omitted. This development is a
-work in progress; some parts may have changed since the overview paper
-above was written.</P>
-
-<P>This document and all Coq source files referenced from it are
-copyright 2005, 2006 Institut National de Recherche en Informatique et
-en Automatique (INRIA) and distributed under the terms of the <A
-HREF="http://www.gnu.org/licenses/gpl.html">GNU General Public
-License</A> version 2.</P>
-
-<H2>Table of contents</H2>
-
-<H3>Libraries, algorithms, data structures</H3>
-
-<UL>
-<LI> <A HREF="lib.Coqlib.html">Coqlib</A>: addendum to the Coq standard library.
- (Coq source file with proofs:
- <A HREF="Coqlib.v"><code>Coqlib.v</code></a>.)
-<LI> <A HREF="lib.Maps.html">Maps</A>: finite maps.
- (Coq source file with proofs:
- <A HREF="Maps.v"><code>Maps.v</code></a>.)
-<LI> <A HREF="lib.Sets.html">Sets</A>: finite sets.
-<LI> <A HREF="lib.union_find.html">Union-find</A>: representation of
-equivalence classes.
- (Coq source file with proofs:
- <A HREF="union_find.v"><code>union_find.v</code></a>.)
-<LI> <A HREF="lib.Inclusion.html">Inclusion</A>: tactics to prove list inclusions.
-<LI> <A HREF="backend.AST.html">AST</A>: identifiers, whole programs and other
-common elements of abstract syntaxes.
- (Coq source file with proofs:
- <A HREF="AST.v"><code>AST.v</code></a>.)
-<LI> <A HREF="lib.Integers.html">Integers</A>: machine integers.
- (Coq source file with proofs:
- <A HREF="Integers.v"><code>Integers.v</code></a>.)
-<LI> <A HREF="lib.Floats.html">Floats</A>: machine floating-point numbers.
-<LI> <A HREF="backend.Mem.html">Mem</A>: the memory model.
-<LI> <A HREF="backend.Globalenvs.html">Globalenvs</A>: global execution environments.
-<LI> <A HREF="backend.Op.html">Op</A>: operators, addressing modes and their
-semantics.
-<LI> <A HREF="lib.Ordered.html">Ordered</A>: construction of
-ordered types.
-<LI> <A HREF="lib.Lattice.html">Lattice</A>: construction of
-semi-lattices.
-<LI> <A HREF="backend.Kildall.html">Kildall</A>: resolution of dataflow
-inequations by fixpoint iteration.
-</UL>
-
-<H3>Source, intermediate and target languages: syntax and semantics</H3>
-
-<UL>
-<LI> <A HREF="backend.Csharpminor.html">Csharpminor</A>: low-level structured language.
-<LI> <A HREF="backend.Cminor.html">Cminor</A>: low-level structured
-language, with explicit stack allocation of certain local variables.
-<LI> <A HREF="backend.RTL.html">RTL</A>: register transfer language (3-address
-code, control-flow graph, infinitely many pseudo-registers). <BR>
-See also: <A HREF="backend.Registers.html">Registers</A> (representation of
-pseudo-registers).
-<LI> <A HREF="backend.LTL.html">LTL</A>: location transfer language (3-address
-code, control-flow graph, finitely many physical registers, infinitely
-many stack slots). <BR>
-See also: <A HREF="backend.Locations.html">Locations</A> (representation of
-locations).
-<LI> <A HREF="backend.Linear.html">Linear</A>: like LTL, but the CFG is
-replaced by a linear list of instructions with explicit branches and labels.
-<LI> <A HREF="backend.Mach.html">Mach</A>: like Linear, with a more concrete
-view of the activation record. <BR>
-See also: an alternate semantics for the same
-syntax is given in <A HREF="backend.Machabstr.html">Machabstr</A>. <BR>
-<LI> <A HREF="backend.PPC.html">PPC</A>: abstract syntax for PowerPC assembly
-code.
-</UL>
-
-<H3>Compiler passes</H3>
-
-<TABLE cellpadding="5%">
-<TR valign="top">
- <TH>Pass</TH>
- <TH>Source &amp; target</TH>
- <TH>Compiler&nbsp;code</TH>
- <TH>Correctness&nbsp;proof</TH>
-</TR>
-
-<TR valign="top">
- <TD>Recognition of operators and addressing modes</TD>
- <TD>Csharpminor to Cminor</TD>
- <TD><A HREF="backend.Cmconstr.html">Cmconstr</A></TD>
- <TD><A HREF="backend.Cmconstrproof.html">Cmconstrproof</A></TD>
-</TR>
-
-<TR valign="top">
- <TD>Stack allocation of local variables<br>whose address is taken</TD>
- <TD>Csharpminor to Cminor</TD>
- <TD><A HREF="backend.Cminorgen.html">Cminorgen</A></TD>
- <TD><A HREF="backend.Cminorgenproof.html">Cminorgenproof</A></TD>
-</TR>
-
-<TR valign="top">
- <TD>Construction of the CFG, <br>3-address code generation</TD>
- <TD>Cminor to RTL</TD>
- <TD><A HREF="backend.RTLgen.html">RTLgen</A></TD>
- <TD><A HREF="backend.RTLgenproof1.html">RTLgenproof1</A><BR>
- <A HREF="backend.RTLgenproof.html">RTLgenproof</A></TD>
-</TR>
-
-<TR valign="top">
- <TD>Constant propagation</TD>
- <TD>RTL to RTL</TD>
- <TD><A HREF="backend.Constprop.html">Constprop</A></TD>
- <TD><A HREF="backend.Constpropproof.html">Constpropproof</A></TD>
-</TR>
-
-<TR valign="top">
- <TD>Common subexpression elimination</TD>
- <TD>RTL to RTL</TD>
- <TD><A HREF="backend.CSE.html">CSE</A></TD>
- <TD><A HREF="backend.CSEproof.html">CSEproof</A></TD>
-</TR>
-
-<TR valign="top">
- <TD>Register allocation by coloring<br>of an interference graph</TD>
- <TD>RTL to LTL</TD>
- <TD><A HREF="backend.Conventions.html">Conventions</A><BR>
- <A HREF="backend.InterfGraph.html">InterfGraph</A><BR>
- <A HREF="backend.Coloring.html">Coloring</A><BR>
- <A HREF="backend.Parallelmove.html">Parallelmove</A><BR>
- <A HREF="backend.Allocation.html">Allocation</A></TD>
- <TD><BR>
- <BR>
- <A HREF="backend.Coloringproof.html">Coloringproof</A><BR>
- <A HREF="backend.Allocproof_aux.html">Allocproof_aux</A><BR>
- <A HREF="backend.Allocproof.html">Allocproof</A></TD>
-</TR>
-
-<TR valign="top">
- <TD>Branch tunneling</TD>
- <TD>LTL to LTL</TD>
- <TD><A HREF="backend.Tunneling.html">Tunneling</A></TD>
- <TD><A HREF="backend.Tunnelingproof.html">Tunnelingproof</A></TD>
-</TR>
-
-<TR valign="top">
- <TD>Linearization of the CFG</TD>
- <TD>LTL to Linear</TD>
- <TD><A HREF="backend.Linearize.html">Linearize</A></TD>
- <TD><A HREF="backend.Linearizeproof.html">Linearizeproof</A></TD>
-</TR>
-
-<TR valign="top">
- <TD>Laying out the activation records</TD>
- <TD>Linear to Mach</TD>
- <TD><A HREF="backend.Stacking.html">Stacking</A></TD>
- <TD><A HREF="backend.Stackingroof.html">Stackingproof</A></TD>
-</TR>
-
-<TR valign="top">
- <TD>Storing the activation records in memory</TD>
- <TD>Mach to Mach</TD>
- <TD>(none)
- <TD><A HREF="backend.Machabstr2mach.html">Machabstr2mach</A></TD>
-
-<TR valign="top">
- <TD>Emission of PowerPC assembly</TD>
- <TD>Mach to PPC</TD>
- <TD><A HREF="backend.PPCgen.html">PPCgen</A></TD>
- <TD><A HREF="backend.PPCgenproof1.html">PPCgenproof1</A><BR>
- <A HREF="backend.PPCgenproof.html">PPCgenproof</A></TD>
-</TR>
-</TABLE>
-
-<H3>Type systems</H3>
-
-Trivial type systems are used to statically capture well-formedness
-conditions on the intermediate languages.
-<UL>
-<LI> <A HREF="backend.RTLtyping.html">RTLtyping</A>: typing for RTL + type
-reconstruction.
-<LI> <A HREF="backend.LTLtyping.html">LTLtyping</A>: typing for LTL.
-<LI> <A HREF="backend.Lineartyping.html">Lineartyping</A>: typing for Linear.
-<LI> <A HREF="backend.Machtyping.html">Machtyping</A>: typing for Mach.
-</UL>
-Proofs that compiler passes are type-preserving:
-<UL>
-<LI> <A HREF="backend.Alloctyping_aux.html">Alloctyping_aux</A> and
- <A HREF="backend.Alloctyping.html">Alloctyping</A> (register allocation).
-<LI> <A HREF="backend.Tunnelingtyping.html">Tunnelingtyping</A> (branch tunneling).
-<LI> <A HREF="backend.Lineartyping.html">Lineartyping</A> (branch tunneling).
-<LI> <A HREF="backend.Stackingtyping.html">Stackingtyping</A> (layout of activation records).
-</UL>
-
-<H3>All together</H3>
-
-<UL>
-<LI> <A HREF="backend.Main.html">Main</A>: composing the passes together; the
-final semantic preservation theorems.
-</UL>
-
-<HR>
-<ADDRESS>Xavier.Leroy@inria.fr</ADDRESS>
-<HR>
-
-</BODY>
-</HTML>
diff --git a/doc/coqdoc.css b/doc/coqdoc.css
new file mode 100644
index 0000000..f2ae96d
--- /dev/null
+++ b/doc/coqdoc.css
@@ -0,0 +1,62 @@
+body {
+ color: black;
+ background: white;
+ margin-left: 15%;
+ margin-right: 5%;
+}
+
+#main a.idref:visited {color : #416DFF; text-decoration : none; }
+#main a.idref:link {color : #416DFF; text-decoration : none; }
+#main a.idref:hover {text-decoration : none; }
+#main a.idref:active {text-decoration : none; }
+
+#main a.modref:visited {color : #416DFF; text-decoration : none; }
+#main a.modref:link {color : #416DFF; text-decoration : none; }
+#main a.modref:hover {text-decoration : none; }
+#main a.modref:active {text-decoration : none; }
+
+#main .keyword { color : #cf1d1d }
+
+#main .doc {
+ margin-left: -5%;
+}
+
+#main span.docright {
+ position: absolute;
+ left: 60%;
+ width: 40%
+}
+
+h1.libtitle {
+ font-size: 2em;
+ margin-left: -15%;
+ margin-right: -5%;
+ text-align: center
+}
+
+h1 {
+ font-size: 1.5em;
+}
+h2 {
+ font-size: 1.17em;
+}
+
+h1, h2 {
+ font-family: sans-serif;
+}
+
+.doc code {
+ color: #008000;
+}
+
+/* Pied de page */
+
+hr { margin-left: -15%; margin-right:-5%; }
+
+#footer { font-size: 0.83em;
+ font-family: sans-serif; }
+
+#footer a:visited { color: blue; }
+#footer a:link { text-decoration: none;
+ color: #888888; }
+
diff --git a/doc/index.html b/doc/index.html
index 33afe85..709767b 100644
--- a/doc/index.html
+++ b/doc/index.html
@@ -1,8295 +1,270 @@
-<html xmlns="http://www.w3.org/1999/xhtml">
-<head>
-<meta http-equiv="Content-Type" content="text/html; charset="><link rel="stylesheet" href="style.css" type="text/css"><title>Index</title>
-</head>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<HTML>
+<HEAD>
+<TITLE>The Compcert certified compiler back-end</TITLE>
+<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
-<body>
+<style type="text/css">
+body {
+ color: black; background: white;
+ margin-left: 5%; margin-right: 5%;
+}
+h2 { margin-left: -5%;}
+h3,h4,h5,h6 { margin-left: -3%; }
+hr { margin-left: -5%; margin-right:-5%; }
+a:visited {color : #416DFF; text-decoration : none; font-weight : bold}
+a:link {color : #416DFF; text-decoration : none; font-weight : bold}
+a:hover {color : Red; text-decoration : underline; }
+a:active {color : Red; text-decoration : underline; }
+</style>
-<table>
-<tr>
-<td>Global Index</td>
-<td><a href="index.html#global_A">A</a></td>
-<td><a href="index.html#global_B">B</a></td>
-<td><a href="index.html#global_C">C</a></td>
-<td><a href="index.html#global_D">D</a></td>
-<td><a href="index.html#global_E">E</a></td>
-<td><a href="index.html#global_F">F</a></td>
-<td><a href="index.html#global_G">G</a></td>
-<td><a href="index.html#global_H">H</a></td>
-<td><a href="index.html#global_I">I</a></td>
-<td>J</td>
-<td><a href="index.html#global_K">K</a></td>
-<td><a href="index.html#global_L">L</a></td>
-<td><a href="index.html#global_M">M</a></td>
-<td><a href="index.html#global_N">N</a></td>
-<td><a href="index.html#global_O">O</a></td>
-<td><a href="index.html#global_P">P</a></td>
-<td>Q</td>
-<td><a href="index.html#global_R">R</a></td>
-<td><a href="index.html#global_S">S</a></td>
-<td><a href="index.html#global_T">T</a></td>
-<td><a href="index.html#global_U">U</a></td>
-<td><a href="index.html#global_V">V</a></td>
-<td><a href="index.html#global_W">W</a></td>
-<td><a href="index.html#global_X">X</a></td>
-<td>Y</td>
-<td><a href="index.html#global_Z">Z</a></td>
-<td><a href="index.html#global__">_</a></td>
-<td>(3806 entries)</td>
-</tr>
-<tr>
-<td>Axiom Index</td>
-<td><a href="index.html#axiom_A">A</a></td>
-<td>B</td>
-<td><a href="index.html#axiom_C">C</a></td>
-<td><a href="index.html#axiom_D">D</a></td>
-<td><a href="index.html#axiom_E">E</a></td>
-<td><a href="index.html#axiom_F">F</a></td>
-<td><a href="index.html#axiom_G">G</a></td>
-<td><a href="index.html#axiom_H">H</a></td>
-<td><a href="index.html#axiom_I">I</a></td>
-<td>J</td>
-<td>K</td>
-<td><a href="index.html#axiom_L">L</a></td>
-<td><a href="index.html#axiom_M">M</a></td>
-<td><a href="index.html#axiom_N">N</a></td>
-<td><a href="index.html#axiom_O">O</a></td>
-<td><a href="index.html#axiom_P">P</a></td>
-<td>Q</td>
-<td>R</td>
-<td><a href="index.html#axiom_S">S</a></td>
-<td>T</td>
-<td>U</td>
-<td>V</td>
-<td>W</td>
-<td>X</td>
-<td>Y</td>
-<td><a href="index.html#axiom_Z">Z</a></td>
-<td>_</td>
-<td>(39 entries)</td>
-</tr>
-<tr>
-<td>Lemma Index</td>
-<td><a href="index.html#lemma_A">A</a></td>
-<td><a href="index.html#lemma_B">B</a></td>
-<td><a href="index.html#lemma_C">C</a></td>
-<td><a href="index.html#lemma_D">D</a></td>
-<td><a href="index.html#lemma_E">E</a></td>
-<td><a href="index.html#lemma_F">F</a></td>
-<td><a href="index.html#lemma_G">G</a></td>
-<td><a href="index.html#lemma_H">H</a></td>
-<td><a href="index.html#lemma_I">I</a></td>
-<td>J</td>
-<td><a href="index.html#lemma_K">K</a></td>
-<td><a href="index.html#lemma_L">L</a></td>
-<td><a href="index.html#lemma_M">M</a></td>
-<td><a href="index.html#lemma_N">N</a></td>
-<td><a href="index.html#lemma_O">O</a></td>
-<td><a href="index.html#lemma_P">P</a></td>
-<td>Q</td>
-<td><a href="index.html#lemma_R">R</a></td>
-<td><a href="index.html#lemma_S">S</a></td>
-<td><a href="index.html#lemma_T">T</a></td>
-<td><a href="index.html#lemma_U">U</a></td>
-<td><a href="index.html#lemma_V">V</a></td>
-<td><a href="index.html#lemma_W">W</a></td>
-<td><a href="index.html#lemma_X">X</a></td>
-<td>Y</td>
-<td><a href="index.html#lemma_Z">Z</a></td>
-<td>_</td>
-<td>(1753 entries)</td>
-</tr>
-<tr>
-<td>Constructor Index</td>
-<td><a href="index.html#constructor_A">A</a></td>
-<td><a href="index.html#constructor_B">B</a></td>
-<td><a href="index.html#constructor_C">C</a></td>
-<td><a href="index.html#constructor_D">D</a></td>
-<td><a href="index.html#constructor_E">E</a></td>
-<td><a href="index.html#constructor_F">F</a></td>
-<td><a href="index.html#constructor_G">G</a></td>
-<td>H</td>
-<td><a href="index.html#constructor_I">I</a></td>
-<td>J</td>
-<td>K</td>
-<td><a href="index.html#constructor_L">L</a></td>
-<td><a href="index.html#constructor_M">M</a></td>
-<td><a href="index.html#constructor_N">N</a></td>
-<td><a href="index.html#constructor_O">O</a></td>
-<td><a href="index.html#constructor_P">P</a></td>
-<td>Q</td>
-<td><a href="index.html#constructor_R">R</a></td>
-<td><a href="index.html#constructor_S">S</a></td>
-<td><a href="index.html#constructor_T">T</a></td>
-<td><a href="index.html#constructor_U">U</a></td>
-<td><a href="index.html#constructor_V">V</a></td>
-<td><a href="index.html#constructor_W">W</a></td>
-<td>X</td>
-<td>Y</td>
-<td>Z</td>
-<td><a href="index.html#constructor__">_</a></td>
-<td>(700 entries)</td>
-</tr>
-<tr>
-<td>Inductive Index</td>
-<td><a href="index.html#inductive_A">A</a></td>
-<td><a href="index.html#inductive_B">B</a></td>
-<td><a href="index.html#inductive_C">C</a></td>
-<td><a href="index.html#inductive_D">D</a></td>
-<td><a href="index.html#inductive_E">E</a></td>
-<td><a href="index.html#inductive_F">F</a></td>
-<td><a href="index.html#inductive_G">G</a></td>
-<td>H</td>
-<td><a href="index.html#inductive_I">I</a></td>
-<td>J</td>
-<td>K</td>
-<td><a href="index.html#inductive_L">L</a></td>
-<td><a href="index.html#inductive_M">M</a></td>
-<td><a href="index.html#inductive_N">N</a></td>
-<td><a href="index.html#inductive_O">O</a></td>
-<td><a href="index.html#inductive_P">P</a></td>
-<td>Q</td>
-<td><a href="index.html#inductive_R">R</a></td>
-<td><a href="index.html#inductive_S">S</a></td>
-<td><a href="index.html#inductive_T">T</a></td>
-<td><a href="index.html#inductive_U">U</a></td>
-<td><a href="index.html#inductive_V">V</a></td>
-<td><a href="index.html#inductive_W">W</a></td>
-<td>X</td>
-<td>Y</td>
-<td>Z</td>
-<td>_</td>
-<td>(155 entries)</td>
-</tr>
-<tr>
-<td>Definition Index</td>
-<td><a href="index.html#definition_A">A</a></td>
-<td><a href="index.html#definition_B">B</a></td>
-<td><a href="index.html#definition_C">C</a></td>
-<td><a href="index.html#definition_D">D</a></td>
-<td><a href="index.html#definition_E">E</a></td>
-<td><a href="index.html#definition_F">F</a></td>
-<td><a href="index.html#definition_G">G</a></td>
-<td><a href="index.html#definition_H">H</a></td>
-<td><a href="index.html#definition_I">I</a></td>
-<td>J</td>
-<td><a href="index.html#definition_K">K</a></td>
-<td><a href="index.html#definition_L">L</a></td>
-<td><a href="index.html#definition_M">M</a></td>
-<td><a href="index.html#definition_N">N</a></td>
-<td><a href="index.html#definition_O">O</a></td>
-<td><a href="index.html#definition_P">P</a></td>
-<td>Q</td>
-<td><a href="index.html#definition_R">R</a></td>
-<td><a href="index.html#definition_S">S</a></td>
-<td><a href="index.html#definition_T">T</a></td>
-<td><a href="index.html#definition_U">U</a></td>
-<td><a href="index.html#definition_V">V</a></td>
-<td><a href="index.html#definition_W">W</a></td>
-<td><a href="index.html#definition_X">X</a></td>
-<td>Y</td>
-<td><a href="index.html#definition_Z">Z</a></td>
-<td>_</td>
-<td>(1017 entries)</td>
-</tr>
-<tr>
-<td>Module Index</td>
-<td><a href="index.html#module_A">A</a></td>
-<td><a href="index.html#module_B">B</a></td>
-<td>C</td>
-<td><a href="index.html#module_D">D</a></td>
-<td><a href="index.html#module_E">E</a></td>
-<td><a href="index.html#module_F">F</a></td>
-<td><a href="index.html#module_G">G</a></td>
-<td>H</td>
-<td><a href="index.html#module_I">I</a></td>
-<td>J</td>
-<td>K</td>
-<td><a href="index.html#module_L">L</a></td>
-<td><a href="index.html#module_M">M</a></td>
-<td><a href="index.html#module_N">N</a></td>
-<td><a href="index.html#module_O">O</a></td>
-<td><a href="index.html#module_P">P</a></td>
-<td>Q</td>
-<td><a href="index.html#module_R">R</a></td>
-<td><a href="index.html#module_S">S</a></td>
-<td><a href="index.html#module_T">T</a></td>
-<td><a href="index.html#module_U">U</a></td>
-<td><a href="index.html#module_V">V</a></td>
-<td>W</td>
-<td>X</td>
-<td>Y</td>
-<td><a href="index.html#module_Z">Z</a></td>
-<td>_</td>
-<td>(78 entries)</td>
-</tr>
-<tr>
-<td>Library Index</td>
-<td><a href="index.html#library_A">A</a></td>
-<td>B</td>
-<td><a href="index.html#library_C">C</a></td>
-<td>D</td>
-<td>E</td>
-<td><a href="index.html#library_F">F</a></td>
-<td><a href="index.html#library_G">G</a></td>
-<td>H</td>
-<td><a href="index.html#library_I">I</a></td>
-<td>J</td>
-<td><a href="index.html#library_K">K</a></td>
-<td><a href="index.html#library_L">L</a></td>
-<td><a href="index.html#library_M">M</a></td>
-<td>N</td>
-<td><a href="index.html#library_O">O</a></td>
-<td><a href="index.html#library_P">P</a></td>
-<td>Q</td>
-<td><a href="index.html#library_R">R</a></td>
-<td><a href="index.html#library_S">S</a></td>
-<td><a href="index.html#library_T">T</a></td>
-<td><a href="index.html#library_U">U</a></td>
-<td><a href="index.html#library_V">V</a></td>
-<td>W</td>
-<td>X</td>
-<td>Y</td>
-<td>Z</td>
-<td>_</td>
-<td>(64 entries)</td>
-</tr>
-</table>
-<hr/>
-<h1>Global Index</h1>
-<a name="global_A"></a><h2>A </h2>
-<a href="backend.Op.html#a">a</a> [inductive, in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Op.html#a">a</a> [inductive, in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Op.html#Abased">Abased</a> [constructor, in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="lib.Floats.html#abs">abs</a> [axiom, in <a href="lib.Floats.html">lib.Floats</a>]<br/>
-<a href="backend.Values.html#absf">absf</a> [definition, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Cmconstr.html#absfloat">absfloat</a> [definition, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="lib.Floats.html#add">add</a> [axiom, in <a href="lib.Floats.html">lib.Floats</a>]<br/>
-<a href="backend.Values.html#add">add</a> [definition, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="lib.Sets.html#add">add</a> [definition, in <a href="lib.Sets.html">lib.Sets</a>]<br/>
-<a href="backend.Cmconstr.html#add">add</a> [definition, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.RTLtyping.html#add">add</a> [definition, in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="lib.Integers.html#add">add</a> [definition, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Cmconstr.html#addf">addf</a> [definition, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Values.html#addf">addf</a> [definition, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Cmconstr.html#addf_cases">addf_cases</a> [inductive, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#addf_case1">addf_case1</a> [constructor, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#addf_case2">addf_case2</a> [constructor, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="lib.Floats.html#addf_commut">addf_commut</a> [axiom, in <a href="lib.Floats.html">lib.Floats</a>]<br/>
-<a href="backend.Values.html#addf_commut">addf_commut</a> [lemma, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Cmconstr.html#addf_default">addf_default</a> [constructor, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#addf_match">addf_match</a> [definition, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#addf_match_aux">addf_match_aux</a> [definition, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.PPCgen.html#addimm">addimm</a> [definition, in <a href="backend.PPCgen.html">backend.PPCgen</a>]<br/>
-<a href="backend.Cmconstr.html#addimm">addimm</a> [definition, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#addimm_cases">addimm_cases</a> [inductive, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#addimm_case1">addimm_case1</a> [constructor, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#addimm_case2">addimm_case2</a> [constructor, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#addimm_case3">addimm_case3</a> [constructor, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#addimm_case4">addimm_case4</a> [constructor, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.PPCgenproof1.html#addimm_correct">addimm_correct</a> [lemma, in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.Cmconstr.html#addimm_default">addimm_default</a> [constructor, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#addimm_match">addimm_match</a> [definition, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.PPCgen.html#addimm_1">addimm_1</a> [definition, in <a href="backend.PPCgen.html">backend.PPCgen</a>]<br/>
-<a href="backend.PPCgenproof1.html#addimm_1_correct">addimm_1_correct</a> [lemma, in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.PPCgen.html#addimm_2">addimm_2</a> [definition, in <a href="backend.PPCgen.html">backend.PPCgen</a>]<br/>
-<a href="backend.PPCgenproof1.html#addimm_2_correct">addimm_2_correct</a> [lemma, in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.Cmconstr.html#addressing">addressing</a> [definition, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Op.html#addressing">addressing</a> [inductive, in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Cmconstr.html#addressing_cases">addressing_cases</a> [inductive, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#addressing_case1">addressing_case1</a> [constructor, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#addressing_case2">addressing_case2</a> [constructor, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#addressing_case3">addressing_case3</a> [constructor, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#addressing_case4">addressing_case4</a> [constructor, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#addressing_case5">addressing_case5</a> [constructor, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#addressing_default">addressing_default</a> [constructor, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#addressing_match">addressing_match</a> [definition, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Mem.html#address_inject">address_inject</a> [lemma, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Constprop.html#addr_strength_reduction">addr_strength_reduction</a> [definition, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#addr_strength_reduction_cases">addr_strength_reduction_cases</a> [inductive, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#addr_strength_reduction_case1">addr_strength_reduction_case1</a> [constructor, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#addr_strength_reduction_case2">addr_strength_reduction_case2</a> [constructor, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#addr_strength_reduction_case3">addr_strength_reduction_case3</a> [constructor, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constpropproof.html#addr_strength_reduction_correct">addr_strength_reduction_correct</a> [lemma, in <a href="backend.Constpropproof.html">backend.Constpropproof</a>]<br/>
-<a href="backend.Constprop.html#addr_strength_reduction_default">addr_strength_reduction_default</a> [constructor, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#addr_strength_reduction_match">addr_strength_reduction_match</a> [definition, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Cminorgen.html#addr_taken_expr">addr_taken_expr</a> [definition, in <a href="backend.Cminorgen.html">backend.Cminorgen</a>]<br/>
-<a href="backend.Cminorgen.html#addr_taken_stmt">addr_taken_stmt</a> [definition, in <a href="backend.Cminorgen.html">backend.Cminorgen</a>]<br/>
-<a href="lib.Integers.html#add_and">add_and</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#add_assoc">add_assoc</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Values.html#add_assoc">add_assoc</a> [lemma, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Allocation.html#add_call">add_call</a> [definition, in <a href="backend.Allocation.html">backend.Allocation</a>]<br/>
-<a href="backend.Allocproof.html#add_call_correct">add_call_correct</a> [lemma, in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.Cmconstr.html#add_cases">add_cases</a> [inductive, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#add_case1">add_case1</a> [constructor, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#add_case2">add_case2</a> [constructor, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#add_case3">add_case3</a> [constructor, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#add_case4">add_case4</a> [constructor, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#add_case5">add_case5</a> [constructor, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="lib.Integers.html#add_commut">add_commut</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Values.html#add_commut">add_commut</a> [lemma, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Allocation.html#add_cond">add_cond</a> [definition, in <a href="backend.Allocation.html">backend.Allocation</a>]<br/>
-<a href="backend.Allocproof.html#add_cond_correct">add_cond_correct</a> [lemma, in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.Cmconstr.html#add_default">add_default</a> [constructor, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Coloring.html#add_edges_instr">add_edges_instr</a> [definition, in <a href="backend.Coloring.html">backend.Coloring</a>]<br/>
-<a href="backend.Coloring.html#add_edges_instrs">add_edges_instrs</a> [definition, in <a href="backend.Coloring.html">backend.Coloring</a>]<br/>
-<a href="backend.Coloringproof.html#add_edges_instrs_correct">add_edges_instrs_correct</a> [lemma, in <a href="backend.Coloringproof.html">backend.Coloringproof</a>]<br/>
-<a href="backend.Coloringproof.html#add_edges_instrs_correct_aux">add_edges_instrs_correct_aux</a> [lemma, in <a href="backend.Coloringproof.html">backend.Coloringproof</a>]<br/>
-<a href="backend.Coloringproof.html#add_edges_instrs_incl_aux">add_edges_instrs_incl_aux</a> [lemma, in <a href="backend.Coloringproof.html">backend.Coloringproof</a>]<br/>
-<a href="backend.Coloringproof.html#add_edges_instr_correct">add_edges_instr_correct</a> [lemma, in <a href="backend.Coloringproof.html">backend.Coloringproof</a>]<br/>
-<a href="backend.Coloringproof.html#add_edges_instr_incl">add_edges_instr_incl</a> [lemma, in <a href="backend.Coloringproof.html">backend.Coloringproof</a>]<br/>
-<a href="backend.Allocation.html#add_entry">add_entry</a> [definition, in <a href="backend.Allocation.html">backend.Allocation</a>]<br/>
-<a href="backend.Allocproof.html#add_entry_correct">add_entry_correct</a> [lemma, in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.Globalenvs.html#add_funct">add_funct</a> [definition, in <a href="backend.Globalenvs.html">backend.Globalenvs</a>]<br/>
-<a href="backend.Globalenvs.html#add_functs">add_functs</a> [definition, in <a href="backend.Globalenvs.html">backend.Globalenvs</a>]<br/>
-<a href="backend.Globalenvs.html#add_functs_transf">add_functs_transf</a> [lemma, in <a href="backend.Globalenvs.html">backend.Globalenvs</a>]<br/>
-<a href="backend.Globalenvs.html#add_globals">add_globals</a> [definition, in <a href="backend.Globalenvs.html">backend.Globalenvs</a>]<br/>
-<a href="backend.RTLgen.html#add_instr">add_instr</a> [definition, in <a href="backend.RTLgen.html">backend.RTLgen</a>]<br/>
-<a href="backend.RTLgenproof1.html#add_instr_at">add_instr_at</a> [lemma, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#add_instr_incr">add_instr_incr</a> [lemma, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgen.html#add_instr_wf">add_instr_wf</a> [lemma, in <a href="backend.RTLgen.html">backend.RTLgen</a>]<br/>
-<a href="backend.InterfGraph.html#add_interf">add_interf</a> [definition, in <a href="backend.InterfGraph.html">backend.InterfGraph</a>]<br/>
-<a href="backend.Coloring.html#add_interf_call">add_interf_call</a> [definition, in <a href="backend.Coloring.html">backend.Coloring</a>]<br/>
-<a href="backend.Coloringproof.html#add_interf_call_correct">add_interf_call_correct</a> [lemma, in <a href="backend.Coloringproof.html">backend.Coloringproof</a>]<br/>
-<a href="backend.Coloringproof.html#add_interf_call_correct_aux_1">add_interf_call_correct_aux_1</a> [lemma, in <a href="backend.Coloringproof.html">backend.Coloringproof</a>]<br/>
-<a href="backend.Coloringproof.html#add_interf_call_correct_aux_2">add_interf_call_correct_aux_2</a> [lemma, in <a href="backend.Coloringproof.html">backend.Coloringproof</a>]<br/>
-<a href="backend.Coloringproof.html#add_interf_call_incl">add_interf_call_incl</a> [lemma, in <a href="backend.Coloringproof.html">backend.Coloringproof</a>]<br/>
-<a href="backend.Coloringproof.html#add_interf_call_incl_aux_1">add_interf_call_incl_aux_1</a> [lemma, in <a href="backend.Coloringproof.html">backend.Coloringproof</a>]<br/>
-<a href="backend.Coloringproof.html#add_interf_call_incl_aux_2">add_interf_call_incl_aux_2</a> [lemma, in <a href="backend.Coloringproof.html">backend.Coloringproof</a>]<br/>
-<a href="backend.InterfGraph.html#add_interf_correct">add_interf_correct</a> [lemma, in <a href="backend.InterfGraph.html">backend.InterfGraph</a>]<br/>
-<a href="backend.Coloring.html#add_interf_entry">add_interf_entry</a> [definition, in <a href="backend.Coloring.html">backend.Coloring</a>]<br/>
-<a href="backend.Coloringproof.html#add_interf_entry_correct">add_interf_entry_correct</a> [lemma, in <a href="backend.Coloringproof.html">backend.Coloringproof</a>]<br/>
-<a href="backend.Coloringproof.html#add_interf_entry_incl">add_interf_entry_incl</a> [lemma, in <a href="backend.Coloringproof.html">backend.Coloringproof</a>]<br/>
-<a href="backend.InterfGraph.html#add_interf_incl">add_interf_incl</a> [lemma, in <a href="backend.InterfGraph.html">backend.InterfGraph</a>]<br/>
-<a href="backend.Coloring.html#add_interf_live">add_interf_live</a> [definition, in <a href="backend.Coloring.html">backend.Coloring</a>]<br/>
-<a href="backend.Coloringproof.html#add_interf_live_correct">add_interf_live_correct</a> [lemma, in <a href="backend.Coloringproof.html">backend.Coloringproof</a>]<br/>
-<a href="backend.Coloringproof.html#add_interf_live_correct_aux">add_interf_live_correct_aux</a> [lemma, in <a href="backend.Coloringproof.html">backend.Coloringproof</a>]<br/>
-<a href="backend.Coloringproof.html#add_interf_live_incl">add_interf_live_incl</a> [lemma, in <a href="backend.Coloringproof.html">backend.Coloringproof</a>]<br/>
-<a href="backend.Coloringproof.html#add_interf_live_incl_aux">add_interf_live_incl_aux</a> [lemma, in <a href="backend.Coloringproof.html">backend.Coloringproof</a>]<br/>
-<a href="backend.Coloring.html#add_interf_move">add_interf_move</a> [definition, in <a href="backend.Coloring.html">backend.Coloring</a>]<br/>
-<a href="backend.Coloringproof.html#add_interf_move_correct">add_interf_move_correct</a> [lemma, in <a href="backend.Coloringproof.html">backend.Coloringproof</a>]<br/>
-<a href="backend.Coloringproof.html#add_interf_move_incl">add_interf_move_incl</a> [lemma, in <a href="backend.Coloringproof.html">backend.Coloringproof</a>]<br/>
-<a href="backend.InterfGraph.html#add_interf_mreg">add_interf_mreg</a> [definition, in <a href="backend.InterfGraph.html">backend.InterfGraph</a>]<br/>
-<a href="backend.InterfGraph.html#add_interf_mreg_correct">add_interf_mreg_correct</a> [lemma, in <a href="backend.InterfGraph.html">backend.InterfGraph</a>]<br/>
-<a href="backend.InterfGraph.html#add_interf_mreg_incl">add_interf_mreg_incl</a> [lemma, in <a href="backend.InterfGraph.html">backend.InterfGraph</a>]<br/>
-<a href="backend.Coloring.html#add_interf_op">add_interf_op</a> [definition, in <a href="backend.Coloring.html">backend.Coloring</a>]<br/>
-<a href="backend.Coloringproof.html#add_interf_op_correct">add_interf_op_correct</a> [lemma, in <a href="backend.Coloringproof.html">backend.Coloringproof</a>]<br/>
-<a href="backend.Coloringproof.html#add_interf_op_incl">add_interf_op_incl</a> [lemma, in <a href="backend.Coloringproof.html">backend.Coloringproof</a>]<br/>
-<a href="backend.Coloring.html#add_interf_params">add_interf_params</a> [definition, in <a href="backend.Coloring.html">backend.Coloring</a>]<br/>
-<a href="backend.Coloringproof.html#add_interf_params_correct">add_interf_params_correct</a> [lemma, in <a href="backend.Coloringproof.html">backend.Coloringproof</a>]<br/>
-<a href="backend.Coloringproof.html#add_interf_params_correct_aux">add_interf_params_correct_aux</a> [lemma, in <a href="backend.Coloringproof.html">backend.Coloringproof</a>]<br/>
-<a href="backend.Coloringproof.html#add_interf_params_incl">add_interf_params_incl</a> [lemma, in <a href="backend.Coloringproof.html">backend.Coloringproof</a>]<br/>
-<a href="backend.Coloringproof.html#add_interf_params_incl_aux">add_interf_params_incl_aux</a> [lemma, in <a href="backend.Coloringproof.html">backend.Coloringproof</a>]<br/>
-<a href="backend.RTLgen.html#add_letvar">add_letvar</a> [definition, in <a href="backend.RTLgen.html">backend.RTLgen</a>]<br/>
-<a href="backend.RTLgenproof1.html#add_letvar_wf">add_letvar_wf</a> [lemma, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.CSE.html#add_load">add_load</a> [definition, in <a href="backend.CSE.html">backend.CSE</a>]<br/>
-<a href="backend.Allocation.html#add_load">add_load</a> [definition, in <a href="backend.Allocation.html">backend.Allocation</a>]<br/>
-<a href="backend.Allocproof.html#add_load_correct">add_load_correct</a> [lemma, in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.CSEproof.html#add_load_satisfiable">add_load_satisfiable</a> [lemma, in <a href="backend.CSEproof.html">backend.CSEproof</a>]<br/>
-<a href="backend.Cmconstr.html#add_match">add_match</a> [definition, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#add_match_aux">add_match_aux</a> [definition, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.RTLgen.html#add_move">add_move</a> [definition, in <a href="backend.RTLgen.html">backend.RTLgen</a>]<br/>
-<a href="backend.Allocation.html#add_move">add_move</a> [definition, in <a href="backend.Allocation.html">backend.Allocation</a>]<br/>
-<a href="backend.RTLgenproof.html#add_move_correct">add_move_correct</a> [lemma, in <a href="backend.RTLgenproof.html">backend.RTLgenproof</a>]<br/>
-<a href="backend.Allocproof.html#add_move_correct">add_move_correct</a> [lemma, in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.RTLgenproof1.html#add_move_incr">add_move_incr</a> [lemma, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="lib.Integers.html#add_neg_zero">add_neg_zero</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Allocation.html#add_op">add_op</a> [definition, in <a href="backend.Allocation.html">backend.Allocation</a>]<br/>
-<a href="backend.CSE.html#add_op">add_op</a> [definition, in <a href="backend.CSE.html">backend.CSE</a>]<br/>
-<a href="backend.Allocproof.html#add_op_correct">add_op_correct</a> [lemma, in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.CSEproof.html#add_op_satisfiable">add_op_satisfiable</a> [lemma, in <a href="backend.CSEproof.html">backend.CSEproof</a>]<br/>
-<a href="backend.Values.html#add_permut">add_permut</a> [lemma, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="lib.Integers.html#add_permut">add_permut</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Values.html#add_permut_4">add_permut_4</a> [lemma, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.InterfGraph.html#add_pref">add_pref</a> [definition, in <a href="backend.InterfGraph.html">backend.InterfGraph</a>]<br/>
-<a href="backend.Coloring.html#add_prefs_call">add_prefs_call</a> [definition, in <a href="backend.Coloring.html">backend.Coloring</a>]<br/>
-<a href="backend.Coloringproof.html#add_prefs_call_incl">add_prefs_call_incl</a> [lemma, in <a href="backend.Coloringproof.html">backend.Coloringproof</a>]<br/>
-<a href="backend.InterfGraph.html#add_pref_incl">add_pref_incl</a> [lemma, in <a href="backend.InterfGraph.html">backend.InterfGraph</a>]<br/>
-<a href="backend.InterfGraph.html#add_pref_mreg">add_pref_mreg</a> [definition, in <a href="backend.InterfGraph.html">backend.InterfGraph</a>]<br/>
-<a href="backend.InterfGraph.html#add_pref_mreg_incl">add_pref_mreg_incl</a> [lemma, in <a href="backend.InterfGraph.html">backend.InterfGraph</a>]<br/>
-<a href="backend.Allocation.html#add_reload">add_reload</a> [definition, in <a href="backend.Allocation.html">backend.Allocation</a>]<br/>
-<a href="backend.Allocation.html#add_reloads">add_reloads</a> [definition, in <a href="backend.Allocation.html">backend.Allocation</a>]<br/>
-<a href="backend.Allocproof.html#add_reloads_correct">add_reloads_correct</a> [lemma, in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.Allocproof.html#add_reloads_correct_rec">add_reloads_correct_rec</a> [lemma, in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.Allocproof.html#add_reload_correct">add_reload_correct</a> [lemma, in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.Allocation.html#add_return">add_return</a> [definition, in <a href="backend.Allocation.html">backend.Allocation</a>]<br/>
-<a href="backend.Allocproof.html#add_return_correct">add_return_correct</a> [lemma, in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.CSE.html#add_rhs">add_rhs</a> [definition, in <a href="backend.CSE.html">backend.CSE</a>]<br/>
-<a href="backend.CSEproof.html#add_rhs_satisfiable">add_rhs_satisfiable</a> [lemma, in <a href="backend.CSEproof.html">backend.CSEproof</a>]<br/>
-<a href="lib.Integers.html#add_signed">add_signed</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Allocation.html#add_spill">add_spill</a> [definition, in <a href="backend.Allocation.html">backend.Allocation</a>]<br/>
-<a href="backend.Allocproof.html#add_spill_correct">add_spill_correct</a> [lemma, in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.Allocation.html#add_store">add_store</a> [definition, in <a href="backend.Allocation.html">backend.Allocation</a>]<br/>
-<a href="backend.Allocproof.html#add_store_correct">add_store_correct</a> [lemma, in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.Kildall.html#add_successors">add_successors</a> [definition, in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Kildall.html#add_successors_correct">add_successors_correct</a> [lemma, in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Globalenvs.html#add_symbol">add_symbol</a> [definition, in <a href="backend.Globalenvs.html">backend.Globalenvs</a>]<br/>
-<a href="backend.Kildall.html#add_to_worklist">add_to_worklist</a> [definition, in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Kildall.html#add_to_worklist_1">add_to_worklist_1</a> [lemma, in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Kildall.html#add_to_worklist_2">add_to_worklist_2</a> [lemma, in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Allocation.html#add_undefs">add_undefs</a> [definition, in <a href="backend.Allocation.html">backend.Allocation</a>]<br/>
-<a href="backend.Allocproof.html#add_undefs_correct">add_undefs_correct</a> [lemma, in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="lib.Integers.html#add_unsigned">add_unsigned</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.RTLgen.html#add_var">add_var</a> [definition, in <a href="backend.RTLgen.html">backend.RTLgen</a>]<br/>
-<a href="backend.RTLgen.html#add_vars">add_vars</a> [definition, in <a href="backend.RTLgen.html">backend.RTLgen</a>]<br/>
-<a href="backend.RTLgenproof1.html#add_vars_incr">add_vars_incr</a> [lemma, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#add_vars_letenv">add_vars_letenv</a> [lemma, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#add_vars_valid">add_vars_valid</a> [lemma, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#add_vars_wf">add_vars_wf</a> [lemma, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#add_var_find">add_var_find</a> [lemma, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#add_var_incr">add_var_incr</a> [lemma, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#add_var_letenv">add_var_letenv</a> [lemma, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#add_var_valid">add_var_valid</a> [lemma, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#add_var_wf">add_var_wf</a> [lemma, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="lib.Integers.html#add_zero">add_zero</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Op.html#Aglobal">Aglobal</a> [constructor, in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Stackingproof.html#agree">agree</a> [inductive, in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="backend.Allocproof.html#agree">agree</a> [definition, in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.PPCgenproof1.html#agree">agree</a> [definition, in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.Allocproof.html#agree_assign_dead">agree_assign_dead</a> [lemma, in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.Allocproof.html#agree_assign_live">agree_assign_live</a> [lemma, in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.Allocproof.html#agree_call">agree_call</a> [lemma, in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.Stackingproof.html#agree_eval_reg">agree_eval_reg</a> [lemma, in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="backend.Allocproof.html#agree_eval_reg">agree_eval_reg</a> [lemma, in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.Stackingproof.html#agree_eval_regs">agree_eval_regs</a> [lemma, in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="backend.Allocproof.html#agree_eval_regs">agree_eval_regs</a> [lemma, in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.Allocproof.html#agree_exten">agree_exten</a> [lemma, in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.PPCgenproof1.html#agree_exten_1">agree_exten_1</a> [lemma, in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.PPCgenproof1.html#agree_exten_2">agree_exten_2</a> [lemma, in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.Allocproof.html#agree_increasing">agree_increasing</a> [lemma, in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.Allocproof.html#agree_init_regs">agree_init_regs</a> [lemma, in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.Allocproof.html#agree_move_live">agree_move_live</a> [lemma, in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.PPCgenproof1.html#agree_nextinstr">agree_nextinstr</a> [lemma, in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.PPCgenproof1.html#agree_nextinstr_commut">agree_nextinstr_commut</a> [lemma, in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.Allocproof.html#agree_parameters">agree_parameters</a> [lemma, in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.Allocproof.html#agree_reg_list_live">agree_reg_list_live</a> [lemma, in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.Allocproof.html#agree_reg_live">agree_reg_live</a> [lemma, in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.Allocproof.html#agree_reg_sum_live">agree_reg_sum_live</a> [lemma, in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.Stackingproof.html#agree_return_regs">agree_return_regs</a> [lemma, in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="backend.PPCgenproof1.html#agree_set_commut">agree_set_commut</a> [lemma, in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.Stackingproof.html#agree_set_local">agree_set_local</a> [lemma, in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="backend.PPCgenproof1.html#agree_set_mfreg">agree_set_mfreg</a> [lemma, in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.PPCgenproof1.html#agree_set_mireg">agree_set_mireg</a> [lemma, in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.PPCgenproof1.html#agree_set_mireg_exten">agree_set_mireg_exten</a> [lemma, in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.PPCgenproof1.html#agree_set_mireg_twice">agree_set_mireg_twice</a> [lemma, in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.PPCgenproof1.html#agree_set_mreg">agree_set_mreg</a> [lemma, in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.PPCgenproof1.html#agree_set_other">agree_set_other</a> [lemma, in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.Stackingproof.html#agree_set_outgoing">agree_set_outgoing</a> [lemma, in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="backend.Stackingproof.html#agree_set_reg">agree_set_reg</a> [lemma, in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="backend.PPCgenproof1.html#agree_set_twice_mireg">agree_set_twice_mireg</a> [lemma, in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.Op.html#Aindexed">Aindexed</a> [constructor, in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Op.html#Aindexed2">Aindexed2</a> [constructor, in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Op.html#Ainstack">Ainstack</a> [constructor, in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="lib.Coqlib.html#align">align</a> [definition, in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#align_le">align_le</a> [lemma, in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="backend.Mach.html#align_16_top">align_16_top</a> [definition, in <a href="backend.Mach.html">backend.Mach</a>]<br/>
-<a href="backend.Mem.html#alloc">alloc</a> [definition, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Allocation.html">Allocation</a> [library]<br/>
-<a href="backend.Allocproof.html">Allocproof</a> [library]<br/>
-<a href="backend.Allocproof_aux.html">Allocproof_aux</a> [library]<br/>
-<a href="backend.Alloctyping.html#allocs_write_ok">allocs_write_ok</a> [lemma, in <a href="backend.Alloctyping.html">backend.Alloctyping</a>]<br/>
-<a href="backend.Alloctyping.html">Alloctyping</a> [library]<br/>
-<a href="backend.Alloctyping_aux.html">Alloctyping_aux</a> [library]<br/>
-<a href="backend.Mem.html#alloc_extends">alloc_extends</a> [lemma, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#alloc_mapped_inject">alloc_mapped_inject</a> [lemma, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Coloring.html#alloc_of_coloring">alloc_of_coloring</a> [definition, in <a href="backend.Coloring.html">backend.Coloring</a>]<br/>
-<a href="backend.Coloringproof.html#alloc_of_coloring_correct_1">alloc_of_coloring_correct_1</a> [lemma, in <a href="backend.Coloringproof.html">backend.Coloringproof</a>]<br/>
-<a href="backend.Coloringproof.html#alloc_of_coloring_correct_2">alloc_of_coloring_correct_2</a> [lemma, in <a href="backend.Coloringproof.html">backend.Coloringproof</a>]<br/>
-<a href="backend.Coloringproof.html#alloc_of_coloring_correct_3">alloc_of_coloring_correct_3</a> [lemma, in <a href="backend.Coloringproof.html">backend.Coloringproof</a>]<br/>
-<a href="backend.Coloringproof.html#alloc_of_coloring_correct_4">alloc_of_coloring_correct_4</a> [lemma, in <a href="backend.Coloringproof.html">backend.Coloringproof</a>]<br/>
-<a href="backend.RTLgen.html#alloc_reg">alloc_reg</a> [definition, in <a href="backend.RTLgen.html">backend.RTLgen</a>]<br/>
-<a href="backend.RTLgen.html#alloc_regs">alloc_regs</a> [definition, in <a href="backend.RTLgen.html">backend.RTLgen</a>]<br/>
-<a href="backend.RTLgenproof1.html#alloc_regs_fresh_or_in_map">alloc_regs_fresh_or_in_map</a> [lemma, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#alloc_regs_incr">alloc_regs_incr</a> [lemma, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#alloc_regs_target_ok">alloc_regs_target_ok</a> [lemma, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#alloc_regs_valid">alloc_regs_valid</a> [lemma, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#alloc_reg_fresh_or_in_map">alloc_reg_fresh_or_in_map</a> [lemma, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#alloc_reg_incr">alloc_reg_incr</a> [lemma, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#alloc_reg_target_ok">alloc_reg_target_ok</a> [lemma, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#alloc_reg_valid">alloc_reg_valid</a> [lemma, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.Mem.html#alloc_right_inject">alloc_right_inject</a> [lemma, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Alloctyping.html#alloc_type">alloc_type</a> [lemma, in <a href="backend.Alloctyping.html">backend.Alloctyping</a>]<br/>
-<a href="backend.Alloctyping.html#alloc_types">alloc_types</a> [lemma, in <a href="backend.Alloctyping.html">backend.Alloctyping</a>]<br/>
-<a href="backend.Mem.html#alloc_unmapped_inject">alloc_unmapped_inject</a> [lemma, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Csharpminor.html#alloc_variables">alloc_variables</a> [inductive, in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Csharpminor.html#alloc_variables_cons">alloc_variables_cons</a> [constructor, in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Cminorgenproof.html#alloc_variables_list_block">alloc_variables_list_block</a> [lemma, in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#alloc_variables_nextblock_incr">alloc_variables_nextblock_incr</a> [lemma, in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Csharpminor.html#alloc_variables_nil">alloc_variables_nil</a> [constructor, in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Alloctyping.html#alloc_write_ok">alloc_write_ok</a> [lemma, in <a href="backend.Alloctyping.html">backend.Alloctyping</a>]<br/>
-<a href="backend.InterfGraph.html#all_interf_regs">all_interf_regs</a> [definition, in <a href="backend.InterfGraph.html">backend.InterfGraph</a>]<br/>
-<a href="backend.InterfGraph.html#all_interf_regs_correct_aux_1">all_interf_regs_correct_aux_1</a> [lemma, in <a href="backend.InterfGraph.html">backend.InterfGraph</a>]<br/>
-<a href="backend.InterfGraph.html#all_interf_regs_correct_aux_2">all_interf_regs_correct_aux_2</a> [lemma, in <a href="backend.InterfGraph.html">backend.InterfGraph</a>]<br/>
-<a href="backend.InterfGraph.html#all_interf_regs_correct_aux_3">all_interf_regs_correct_aux_3</a> [lemma, in <a href="backend.InterfGraph.html">backend.InterfGraph</a>]<br/>
-<a href="backend.InterfGraph.html#all_interf_regs_correct_1">all_interf_regs_correct_1</a> [lemma, in <a href="backend.InterfGraph.html">backend.InterfGraph</a>]<br/>
-<a href="backend.InterfGraph.html#all_interf_regs_correct_2">all_interf_regs_correct_2</a> [lemma, in <a href="backend.InterfGraph.html">backend.InterfGraph</a>]<br/>
-<a href="backend.CSEproof.html#analysis_correct_entry">analysis_correct_entry</a> [lemma, in <a href="backend.CSEproof.html">backend.CSEproof</a>]<br/>
-<a href="backend.CSEproof.html#analysis_correct_N">analysis_correct_N</a> [lemma, in <a href="backend.CSEproof.html">backend.CSEproof</a>]<br/>
-<a href="backend.CSEproof.html#analysis_correct_1">analysis_correct_1</a> [lemma, in <a href="backend.CSEproof.html">backend.CSEproof</a>]<br/>
-<a href="backend.Allocation.html#analyze">analyze</a> [definition, in <a href="backend.Allocation.html">backend.Allocation</a>]<br/>
-<a href="backend.Constprop.html#analyze">analyze</a> [definition, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.CSE.html#analyze">analyze</a> [definition, in <a href="backend.CSE.html">backend.CSE</a>]<br/>
-<a href="backend.Allocproof.html#analyze_correct">analyze_correct</a> [lemma, in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.Constpropproof.html#analyze_correct_1">analyze_correct_1</a> [lemma, in <a href="backend.Constpropproof.html">backend.Constpropproof</a>]<br/>
-<a href="backend.Constpropproof.html#analyze_correct_2">analyze_correct_2</a> [lemma, in <a href="backend.Constpropproof.html">backend.Constpropproof</a>]<br/>
-<a href="backend.Constpropproof.html#analyze_correct_3">analyze_correct_3</a> [lemma, in <a href="backend.Constpropproof.html">backend.Constpropproof</a>]<br/>
-<a href="backend.Kildall.html#analyze_invariant">analyze_invariant</a> [lemma, in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Kildall.html#analyze_P">analyze_P</a> [lemma, in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="lib.Integers.html#and">and</a> [definition, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Cmconstr.html#and">and</a> [definition, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Values.html#and">and</a> [definition, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Cmconstr.html#andimm">andimm</a> [definition, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.PPCgen.html#andimm">andimm</a> [definition, in <a href="backend.PPCgen.html">backend.PPCgen</a>]<br/>
-<a href="backend.PPCgenproof1.html#andimm_correct">andimm_correct</a> [lemma, in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.Values.html#and_assoc">and_assoc</a> [lemma, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="lib.Integers.html#and_assoc">and_assoc</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#and_commut">and_commut</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Values.html#and_commut">and_commut</a> [lemma, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="lib.Integers.html#and_idem">and_idem</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#and_mone">and_mone</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#and_or_distrib">and_or_distrib</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#and_shl">and_shl</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#and_shru">and_shru</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#and_xor_distrib">and_xor_distrib</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#and_zero">and_zero</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Parallelmove.html#appcons_length">appcons_length</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="lib.Maps.html#append">append</a> [definition, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#append_assoc_0">append_assoc_0</a> [lemma, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#append_assoc_1">append_assoc_1</a> [lemma, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#append_injective">append_injective</a> [lemma, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#append_neutral_l">append_neutral_l</a> [lemma, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#append_neutral_r">append_neutral_r</a> [lemma, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="backend.Main.html#apply_partial">apply_partial</a> [definition, in <a href="backend.Main.html">backend.Main</a>]<br/>
-<a href="backend.Main.html#apply_total">apply_total</a> [definition, in <a href="backend.Main.html">backend.Main</a>]<br/>
-<a href="backend.Main.html#apply_total_transf_program">apply_total_transf_program</a> [lemma, in <a href="backend.Main.html">backend.Main</a>]<br/>
-<a href="backend.Constprop.html#approx">approx</a> [inductive, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#Approx">Approx</a> [module, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#approx_regs">approx_regs</a> [definition, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constpropproof.html#approx_regs_val_list">approx_regs_val_list</a> [lemma, in <a href="backend.Constpropproof.html">backend.Constpropproof</a>]<br/>
-<a href="backend.Parallelmove.html#app_app">app_app</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#app_cons">app_cons</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#app_nil">app_nil</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#app_rewrite">app_rewrite</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#app_rewriter">app_rewriter</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#app_rewrite2">app_rewrite2</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Conventions.html#arguments_not_preserved">arguments_not_preserved</a> [lemma, in <a href="backend.Conventions.html">backend.Conventions</a>]<br/>
-<a href="backend.Cminorgen.html#assign_variable">assign_variable</a> [definition, in <a href="backend.Cminorgen.html">backend.Cminorgen</a>]<br/>
-<a href="backend.Cminorgen.html#assign_variables">assign_variables</a> [definition, in <a href="backend.Cminorgen.html">backend.Cminorgen</a>]<br/>
-<a href="backend.AST.html">AST</a> [library]<br/>
-<br/><br/><a name="global_B"></a><h2>B </h2>
-<a href="backend.Kildall.html#BACKWARD_DATAFLOW_SOLVER">BACKWARD_DATAFLOW_SOLVER</a> [module, in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Kildall.html#Backward_Dataflow_Solver">Backward_Dataflow_Solver</a> [module, in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Parallelmove.html#base_case_Pmov_dec">base_case_Pmov_dec</a> [definition, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Kildall.html#basic_block_list">basic_block_list</a> [definition, in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Kildall.html#basic_block_map">basic_block_map</a> [definition, in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Kildall.html#BBlock_solver">BBlock_solver</a> [module, in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Kildall.html#BBLOCK_SOLVER">BBLOCK_SOLVER</a> [module, in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Kildall.html#bbmap">bbmap</a> [definition, in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.LTL.html#Bcall">Bcall</a> [constructor, in <a href="backend.LTL.html">backend.LTL</a>]<br/>
-<a href="backend.LTL.html#Bcond">Bcond</a> [constructor, in <a href="backend.LTL.html">backend.LTL</a>]<br/>
-<a href="backend.LTL.html#Bgetstack">Bgetstack</a> [constructor, in <a href="backend.LTL.html">backend.LTL</a>]<br/>
-<a href="backend.LTL.html#Bgoto">Bgoto</a> [constructor, in <a href="backend.LTL.html">backend.LTL</a>]<br/>
-<a href="lib.Inclusion.html#bin">bin</a> [inductive, in <a href="lib.Inclusion.html">lib.Inclusion</a>]<br/>
-<a href="backend.RTLgen.html#bind">bind</a> [definition, in <a href="backend.RTLgen.html">backend.RTLgen</a>]<br/>
-<a href="backend.Cminorgen.html#bind">bind</a> [definition, in <a href="backend.Cminorgen.html">backend.Cminorgen</a>]<br/>
-<a href="backend.RTLgen.html#bind2">bind2</a> [definition, in <a href="backend.RTLgen.html">backend.RTLgen</a>]<br/>
-<a href="backend.Csharpminor.html#bind_parameters">bind_parameters</a> [inductive, in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Csharpminor.html#bind_parameters_cons">bind_parameters_cons</a> [constructor, in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Cminorgenproof.html#bind_parameters_length">bind_parameters_length</a> [lemma, in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Csharpminor.html#bind_parameters_nil">bind_parameters_nil</a> [constructor, in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="lib.Inclusion.html#bin_A">bin_A</a> [definition, in <a href="lib.Inclusion.html">lib.Inclusion</a>]<br/>
-<a href="lib.Integers.html#bits_of_Z">bits_of_Z</a> [definition, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#bits_of_Z_above">bits_of_Z_above</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#bits_of_Z_below">bits_of_Z_below</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#bits_of_Z_mone">bits_of_Z_mone</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#bits_of_Z_of_bits">bits_of_Z_of_bits</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#bits_of_Z_zero">bits_of_Z_zero</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#bitwise_binop">bitwise_binop</a> [definition, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#bitwise_binop_assoc">bitwise_binop_assoc</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#bitwise_binop_commut">bitwise_binop_commut</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#bitwise_binop_idem">bitwise_binop_idem</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#bitwise_binop_rol">bitwise_binop_rol</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#bitwise_binop_shl">bitwise_binop_shl</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#bitwise_binop_shru">bitwise_binop_shru</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.LTL.html#Bload">Bload</a> [constructor, in <a href="backend.LTL.html">backend.LTL</a>]<br/>
-<a href="backend.LTL.html#block">block</a> [inductive, in <a href="backend.LTL.html">backend.LTL</a>]<br/>
-<a href="backend.Values.html#block">block</a> [definition, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Mem.html#block_agree">block_agree</a> [definition, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#block_agree_refl">block_agree_refl</a> [lemma, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#block_agree_sym">block_agree_sym</a> [lemma, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#block_agree_trans">block_agree_trans</a> [lemma, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#block_contents">block_contents</a> [inductive, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#block_contents_agree">block_contents_agree</a> [definition, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#block_contents_exten">block_contents_exten</a> [lemma, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#block_contents_extends">block_contents_extends</a> [definition, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#block_contents_inject">block_contents_inject</a> [inductive, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#block_contents_inject_incr">block_contents_inject_incr</a> [lemma, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#block_cont_val">block_cont_val</a> [lemma, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Values.html#bool_of_false_val">bool_of_false_val</a> [lemma, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Values.html#bool_of_false_val2">bool_of_false_val2</a> [lemma, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Values.html#bool_of_false_val_inv">bool_of_false_val_inv</a> [lemma, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Values.html#bool_of_true_val">bool_of_true_val</a> [lemma, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Values.html#bool_of_true_val2">bool_of_true_val2</a> [lemma, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Values.html#bool_of_true_val_inv">bool_of_true_val_inv</a> [lemma, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Values.html#bool_of_val">bool_of_val</a> [inductive, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Values.html#bool_of_val_int_true">bool_of_val_int_true</a> [constructor, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.LTL.html#Bop">Bop</a> [constructor, in <a href="backend.LTL.html">backend.LTL</a>]<br/>
-<a href="lib.Lattice.html#bot">bot</a> [definition, in <a href="lib.Lattice.html">lib.Lattice</a>]<br/>
-<a href="lib.Lattice.html#Bot">Bot</a> [constructor, in <a href="lib.Lattice.html">lib.Lattice</a>]<br/>
-<a href="lib.Lattice.html#bot">bot</a> [definition, in <a href="lib.Lattice.html">lib.Lattice</a>]<br/>
-<a href="backend.Constprop.html#bot">bot</a> [definition, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="lib.Sets.html#bot">bot</a> [definition, in <a href="lib.Sets.html">lib.Sets</a>]<br/>
-<a href="lib.Lattice.html#bot">bot</a> [definition, in <a href="lib.Lattice.html">lib.Lattice</a>]<br/>
-<a href="lib.Lattice.html#Bot_except">Bot_except</a> [constructor, in <a href="lib.Lattice.html">lib.Lattice</a>]<br/>
-<a href="backend.Lineartyping.html#bounds">bounds</a> [inductive, in <a href="backend.Lineartyping.html">backend.Lineartyping</a>]<br/>
-<a href="backend.Mem.html#bounds_free_block">bounds_free_block</a> [lemma, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Lineartyping.html#bound_float_callee_save_pos">bound_float_callee_save_pos</a> [lemma, in <a href="backend.Lineartyping.html">backend.Lineartyping</a>]<br/>
-<a href="backend.Lineartyping.html#bound_float_local_pos">bound_float_local_pos</a> [lemma, in <a href="backend.Lineartyping.html">backend.Lineartyping</a>]<br/>
-<a href="backend.Lineartyping.html#bound_int_callee_save_pos">bound_int_callee_save_pos</a> [lemma, in <a href="backend.Lineartyping.html">backend.Lineartyping</a>]<br/>
-<a href="backend.Lineartyping.html#bound_int_local_pos">bound_int_local_pos</a> [lemma, in <a href="backend.Lineartyping.html">backend.Lineartyping</a>]<br/>
-<a href="backend.Lineartyping.html#bound_outgoing_pos">bound_outgoing_pos</a> [lemma, in <a href="backend.Lineartyping.html">backend.Lineartyping</a>]<br/>
-<a href="backend.Tunneling.html#branch_target">branch_target</a> [definition, in <a href="backend.Tunneling.html">backend.Tunneling</a>]<br/>
-<a href="backend.Tunnelingproof.html#branch_target_characterization">branch_target_characterization</a> [lemma, in <a href="backend.Tunnelingproof.html">backend.Tunnelingproof</a>]<br/>
-<a href="backend.Tunneling.html#branch_target_rec">branch_target_rec</a> [definition, in <a href="backend.Tunneling.html">backend.Tunneling</a>]<br/>
-<a href="backend.Tunnelingproof.html#branch_target_rec_1">branch_target_rec_1</a> [lemma, in <a href="backend.Tunnelingproof.html">backend.Tunnelingproof</a>]<br/>
-<a href="backend.Tunnelingproof.html#branch_target_rec_2">branch_target_rec_2</a> [lemma, in <a href="backend.Tunnelingproof.html">backend.Tunnelingproof</a>]<br/>
-<a href="backend.LTL.html#Breturn">Breturn</a> [constructor, in <a href="backend.LTL.html">backend.LTL</a>]<br/>
-<a href="backend.LTL.html#Bsetstack">Bsetstack</a> [constructor, in <a href="backend.LTL.html">backend.LTL</a>]<br/>
-<a href="backend.LTL.html#Bstore">Bstore</a> [constructor, in <a href="backend.LTL.html">backend.LTL</a>]<br/>
-<a href="backend.Cminorgen.html#build_compilenv">build_compilenv</a> [definition, in <a href="backend.Cminorgen.html">backend.Cminorgen</a>]<br/>
-<br/><br/><a name="global_C"></a><h2>C </h2>
-<a href="backend.Machabstr2mach.html#callstack">callstack</a> [definition, in <a href="backend.Machabstr2mach.html">backend.Machabstr2mach</a>]<br/>
-<a href="backend.Cminorgenproof.html#callstack">callstack</a> [definition, in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Machabstr2mach.html#callstack_dom">callstack_dom</a> [inductive, in <a href="backend.Machabstr2mach.html">backend.Machabstr2mach</a>]<br/>
-<a href="backend.Machabstr2mach.html#callstack_dom_cons">callstack_dom_cons</a> [constructor, in <a href="backend.Machabstr2mach.html">backend.Machabstr2mach</a>]<br/>
-<a href="backend.Machabstr2mach.html#callstack_dom_diff">callstack_dom_diff</a> [lemma, in <a href="backend.Machabstr2mach.html">backend.Machabstr2mach</a>]<br/>
-<a href="backend.Machabstr2mach.html#callstack_dom_incr">callstack_dom_incr</a> [lemma, in <a href="backend.Machabstr2mach.html">backend.Machabstr2mach</a>]<br/>
-<a href="backend.Machabstr2mach.html#callstack_dom_less">callstack_dom_less</a> [lemma, in <a href="backend.Machabstr2mach.html">backend.Machabstr2mach</a>]<br/>
-<a href="backend.Machabstr2mach.html#callstack_dom_nil">callstack_dom_nil</a> [constructor, in <a href="backend.Machabstr2mach.html">backend.Machabstr2mach</a>]<br/>
-<a href="backend.Machabstr2mach.html#callstack_exten">callstack_exten</a> [lemma, in <a href="backend.Machabstr2mach.html">backend.Machabstr2mach</a>]<br/>
-<a href="backend.Machabstr2mach.html#callstack_function_entry">callstack_function_entry</a> [lemma, in <a href="backend.Machabstr2mach.html">backend.Machabstr2mach</a>]<br/>
-<a href="backend.Machabstr2mach.html#callstack_function_return">callstack_function_return</a> [lemma, in <a href="backend.Machabstr2mach.html">backend.Machabstr2mach</a>]<br/>
-<a href="backend.Machabstr2mach.html#callstack_get_parent">callstack_get_parent</a> [lemma, in <a href="backend.Machabstr2mach.html">backend.Machabstr2mach</a>]<br/>
-<a href="backend.Machabstr2mach.html#callstack_get_slot">callstack_get_slot</a> [lemma, in <a href="backend.Machabstr2mach.html">backend.Machabstr2mach</a>]<br/>
-<a href="backend.Machabstr2mach.html#callstack_init">callstack_init</a> [lemma, in <a href="backend.Machabstr2mach.html">backend.Machabstr2mach</a>]<br/>
-<a href="backend.Machabstr2mach.html#callstack_invariant">callstack_invariant</a> [inductive, in <a href="backend.Machabstr2mach.html">backend.Machabstr2mach</a>]<br/>
-<a href="backend.Machabstr2mach.html#callstack_linked">callstack_linked</a> [inductive, in <a href="backend.Machabstr2mach.html">backend.Machabstr2mach</a>]<br/>
-<a href="backend.Machabstr2mach.html#callstack_linked_cons">callstack_linked_cons</a> [constructor, in <a href="backend.Machabstr2mach.html">backend.Machabstr2mach</a>]<br/>
-<a href="backend.Machabstr2mach.html#callstack_linked_nil">callstack_linked_nil</a> [constructor, in <a href="backend.Machabstr2mach.html">backend.Machabstr2mach</a>]<br/>
-<a href="backend.Machabstr2mach.html#callstack_linked_one">callstack_linked_one</a> [constructor, in <a href="backend.Machabstr2mach.html">backend.Machabstr2mach</a>]<br/>
-<a href="backend.Machabstr2mach.html#callstack_load">callstack_load</a> [lemma, in <a href="backend.Machabstr2mach.html">backend.Machabstr2mach</a>]<br/>
-<a href="backend.Machabstr2mach.html#callstack_set_slot">callstack_set_slot</a> [lemma, in <a href="backend.Machabstr2mach.html">backend.Machabstr2mach</a>]<br/>
-<a href="backend.Machabstr2mach.html#callstack_store">callstack_store</a> [lemma, in <a href="backend.Machabstr2mach.html">backend.Machabstr2mach</a>]<br/>
-<a href="backend.Machabstr2mach.html#callstack_store_aux">callstack_store_aux</a> [lemma, in <a href="backend.Machabstr2mach.html">backend.Machabstr2mach</a>]<br/>
-<a href="backend.Machabstr2mach.html#callstack_store_ok">callstack_store_ok</a> [lemma, in <a href="backend.Machabstr2mach.html">backend.Machabstr2mach</a>]<br/>
-<a href="backend.LTL.html#call_regs">call_regs</a> [definition, in <a href="backend.LTL.html">backend.LTL</a>]<br/>
-<a href="backend.Allocproof.html#call_regs_param_of_arg">call_regs_param_of_arg</a> [lemma, in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.PPC.html#CARRY">CARRY</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.Csharpminor.html#cast">cast</a> [definition, in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="lib.Integers.html#cast16signed">cast16signed</a> [definition, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Values.html#cast16signed">cast16signed</a> [definition, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Cmconstr.html#cast16signed">cast16signed</a> [definition, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#cast16unsigned">cast16unsigned</a> [definition, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Values.html#cast16unsigned">cast16unsigned</a> [definition, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="lib.Integers.html#cast16unsigned">cast16unsigned</a> [definition, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#cast16unsigned_and">cast16unsigned_and</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Values.html#cast16unsigned_and">cast16unsigned_and</a> [lemma, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="lib.Integers.html#cast16_signed_equal_if_unsigned_equal">cast16_signed_equal_if_unsigned_equal</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#cast16_signed_idem">cast16_signed_idem</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#cast16_unsigned_idem">cast16_unsigned_idem</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#cast16_unsigned_signed">cast16_unsigned_signed</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Cmconstr.html#cast8signed">cast8signed</a> [definition, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="lib.Integers.html#cast8signed">cast8signed</a> [definition, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Values.html#cast8signed">cast8signed</a> [definition, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Cmconstr.html#cast8unsigned">cast8unsigned</a> [definition, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Values.html#cast8unsigned">cast8unsigned</a> [definition, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="lib.Integers.html#cast8unsigned">cast8unsigned</a> [definition, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#cast8unsigned_and">cast8unsigned_and</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Values.html#cast8unsigned_and">cast8unsigned_and</a> [lemma, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="lib.Integers.html#cast8_signed_equal_if_unsigned_equal">cast8_signed_equal_if_unsigned_equal</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#cast8_signed_idem">cast8_signed_idem</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#cast8_signed_unsigned">cast8_signed_unsigned</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#cast8_unsigned_idem">cast8_unsigned_idem</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#cast8_unsigned_signed">cast8_unsigned_signed</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Op.html#Ccomp">Ccomp</a> [constructor, in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Op.html#Ccompf">Ccompf</a> [constructor, in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Op.html#Ccompimm">Ccompimm</a> [constructor, in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Op.html#Ccompu">Ccompu</a> [constructor, in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Op.html#Ccompuimm">Ccompuimm</a> [constructor, in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Cminor.html#CEcond">CEcond</a> [constructor, in <a href="backend.Cminor.html">backend.Cminor</a>]<br/>
-<a href="backend.Cminor.html#CEcondition">CEcondition</a> [constructor, in <a href="backend.Cminor.html">backend.Cminor</a>]<br/>
-<a href="backend.Cminor.html#CEfalse">CEfalse</a> [constructor, in <a href="backend.Cminor.html">backend.Cminor</a>]<br/>
-<a href="backend.AST.html#Ceq">Ceq</a> [constructor, in <a href="backend.AST.html">backend.AST</a>]<br/>
-<a href="backend.Cminor.html#CEtrue">CEtrue</a> [constructor, in <a href="backend.Cminor.html">backend.Cminor</a>]<br/>
-<a href="backend.AST.html#Cge">Cge</a> [constructor, in <a href="backend.AST.html">backend.AST</a>]<br/>
-<a href="backend.AST.html#Cgt">Cgt</a> [constructor, in <a href="backend.AST.html">backend.AST</a>]<br/>
-<a href="lib.Inclusion.html#check_all_leaves">check_all_leaves</a> [definition, in <a href="lib.Inclusion.html">lib.Inclusion</a>]<br/>
-<a href="lib.Inclusion.html#check_all_leaves_sound">check_all_leaves_sound</a> [lemma, in <a href="lib.Inclusion.html">lib.Inclusion</a>]<br/>
-<a href="backend.Coloring.html#check_coloring">check_coloring</a> [definition, in <a href="backend.Coloring.html">backend.Coloring</a>]<br/>
-<a href="backend.Coloring.html#check_coloring_1">check_coloring_1</a> [definition, in <a href="backend.Coloring.html">backend.Coloring</a>]<br/>
-<a href="backend.Coloringproof.html#check_coloring_1_correct">check_coloring_1_correct</a> [lemma, in <a href="backend.Coloringproof.html">backend.Coloringproof</a>]<br/>
-<a href="backend.Coloring.html#check_coloring_2">check_coloring_2</a> [definition, in <a href="backend.Coloring.html">backend.Coloring</a>]<br/>
-<a href="backend.Coloringproof.html#check_coloring_2_correct">check_coloring_2_correct</a> [lemma, in <a href="backend.Coloringproof.html">backend.Coloringproof</a>]<br/>
-<a href="backend.Coloring.html#check_coloring_3">check_coloring_3</a> [definition, in <a href="backend.Coloring.html">backend.Coloring</a>]<br/>
-<a href="backend.Coloringproof.html#check_coloring_3_correct">check_coloring_3_correct</a> [lemma, in <a href="backend.Coloringproof.html">backend.Coloringproof</a>]<br/>
-<a href="backend.Mem.html#check_cont">check_cont</a> [definition, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#check_cont_agree">check_cont_agree</a> [lemma, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#check_cont_false">check_cont_false</a> [lemma, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#check_cont_inject">check_cont_inject</a> [lemma, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#check_cont_inv">check_cont_inv</a> [lemma, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#check_cont_true">check_cont_true</a> [lemma, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="lib.Integers.html#check_equal_on_range">check_equal_on_range</a> [definition, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#check_equal_on_range_correct">check_equal_on_range_correct</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Mach.html#chunk_of_type">chunk_of_type</a> [definition, in <a href="backend.Mach.html">backend.Mach</a>]<br/>
-<a href="backend.PPC.html#Cint">Cint</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.AST.html#Cle">Cle</a> [constructor, in <a href="backend.AST.html">backend.AST</a>]<br/>
-<a href="backend.Linearize.html#cleanup_code">cleanup_code</a> [definition, in <a href="backend.Linearize.html">backend.Linearize</a>]<br/>
-<a href="backend.Linearizetyping.html#cleanup_code_conservation">cleanup_code_conservation</a> [lemma, in <a href="backend.Linearizetyping.html">backend.Linearizetyping</a>]<br/>
-<a href="backend.Linearizetyping.html#cleanup_code_conservation_2">cleanup_code_conservation_2</a> [lemma, in <a href="backend.Linearizetyping.html">backend.Linearizetyping</a>]<br/>
-<a href="backend.Linearizeproof.html#cleanup_code_correct_1">cleanup_code_correct_1</a> [lemma, in <a href="backend.Linearizeproof.html">backend.Linearizeproof</a>]<br/>
-<a href="backend.Linearizeproof.html#cleanup_code_correct_2">cleanup_code_correct_2</a> [lemma, in <a href="backend.Linearizeproof.html">backend.Linearizeproof</a>]<br/>
-<a href="backend.Linearize.html#cleanup_function">cleanup_function</a> [definition, in <a href="backend.Linearize.html">backend.Linearize</a>]<br/>
-<a href="backend.Linearizetyping.html#cleanup_function_conservation">cleanup_function_conservation</a> [lemma, in <a href="backend.Linearizetyping.html">backend.Linearizetyping</a>]<br/>
-<a href="backend.Linearizetyping.html#cleanup_function_conservation_2">cleanup_function_conservation_2</a> [lemma, in <a href="backend.Linearizetyping.html">backend.Linearizetyping</a>]<br/>
-<a href="backend.Linearizeproof.html#cleanup_function_correct">cleanup_function_correct</a> [lemma, in <a href="backend.Linearizeproof.html">backend.Linearizeproof</a>]<br/>
-<a href="backend.AST.html#Clt">Clt</a> [constructor, in <a href="backend.AST.html">backend.AST</a>]<br/>
-<a href="backend.Op.html#Cmasknotzero">Cmasknotzero</a> [constructor, in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Op.html#Cmaskzero">Cmaskzero</a> [constructor, in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Cmconstr.html">Cmconstr</a> [library]<br/>
-<a href="backend.Cmconstrproof.html">Cmconstrproof</a> [library]<br/>
-<a href="backend.Cminor.html">Cminor</a> [library]<br/>
-<a href="backend.Cminorgen.html">Cminorgen</a> [library]<br/>
-<a href="backend.Cminorgenproof.html">Cminorgenproof</a> [library]<br/>
-<a href="lib.Floats.html#cmp">cmp</a> [axiom, in <a href="lib.Floats.html">lib.Floats</a>]<br/>
-<a href="backend.Cmconstr.html#cmp">cmp</a> [definition, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Values.html#cmp">cmp</a> [definition, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="lib.Integers.html#cmp">cmp</a> [definition, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Cmconstr.html#cmpf">cmpf</a> [definition, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Values.html#cmpf">cmpf</a> [definition, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Values.html#cmpf_ge">cmpf_ge</a> [lemma, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Values.html#cmpf_is_bool">cmpf_is_bool</a> [lemma, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Values.html#cmpf_le">cmpf_le</a> [lemma, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Values.html#cmpu">cmpu</a> [definition, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Cmconstr.html#cmpu">cmpu</a> [definition, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="lib.Integers.html#cmpu">cmpu</a> [definition, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Values.html#cmpu_is_bool">cmpu_is_bool</a> [lemma, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="lib.Floats.html#cmp_ge_gt_eq">cmp_ge_gt_eq</a> [axiom, in <a href="lib.Floats.html">lib.Floats</a>]<br/>
-<a href="backend.Values.html#cmp_is_bool">cmp_is_bool</a> [lemma, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="lib.Floats.html#cmp_le_lt_eq">cmp_le_lt_eq</a> [axiom, in <a href="lib.Floats.html">lib.Floats</a>]<br/>
-<a href="backend.Values.html#cmp_mismatch">cmp_mismatch</a> [definition, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Values.html#cmp_mismatch_is_bool">cmp_mismatch_is_bool</a> [lemma, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="lib.Floats.html#cmp_ne_eq">cmp_ne_eq</a> [axiom, in <a href="lib.Floats.html">lib.Floats</a>]<br/>
-<a href="backend.AST.html#Cne">Cne</a> [constructor, in <a href="backend.AST.html">backend.AST</a>]<br/>
-<a href="backend.Op.html#Cnotcompf">Cnotcompf</a> [constructor, in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.LTL.html#code">code</a> [definition, in <a href="backend.LTL.html">backend.LTL</a>]<br/>
-<a href="backend.PPC.html#code">code</a> [definition, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.RTL.html#code">code</a> [definition, in <a href="backend.RTL.html">backend.RTL</a>]<br/>
-<a href="backend.Linear.html#code">code</a> [definition, in <a href="backend.Linear.html">backend.Linear</a>]<br/>
-<a href="backend.Mach.html#code">code</a> [definition, in <a href="backend.Mach.html">backend.Mach</a>]<br/>
-<a href="backend.PPCgen.html#code_size">code_size</a> [definition, in <a href="backend.PPCgen.html">backend.PPCgen</a>]<br/>
-<a href="backend.PPCgenproof.html#code_tail">code_tail</a> [definition, in <a href="backend.PPCgenproof.html">backend.PPCgenproof</a>]<br/>
-<a href="backend.PPCgenproof.html#code_tail_next">code_tail_next</a> [lemma, in <a href="backend.PPCgenproof.html">backend.PPCgenproof</a>]<br/>
-<a href="backend.PPCgenproof.html#code_tail_next_int">code_tail_next_int</a> [lemma, in <a href="backend.PPCgenproof.html">backend.PPCgenproof</a>]<br/>
-<a href="backend.Coloring.html">Coloring</a> [library]<br/>
-<a href="backend.Coloringproof.html">Coloringproof</a> [library]<br/>
-<a href="lib.Maps.html#combine">combine</a> [definition, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#combine_commut">combine_commut</a> [lemma, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Ordered.html#compare">compare</a> [lemma, in <a href="lib.Ordered.html">lib.Ordered</a>]<br/>
-<a href="lib.Ordered.html#compare">compare</a> [lemma, in <a href="lib.Ordered.html">lib.Ordered</a>]<br/>
-<a href="lib.Ordered.html#compare">compare</a> [lemma, in <a href="lib.Ordered.html">lib.Ordered</a>]<br/>
-<a href="backend.PPC.html#compare_float">compare_float</a> [definition, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPCgenproof1.html#compare_float_spec">compare_float_spec</a> [lemma, in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.PPC.html#compare_sint">compare_sint</a> [definition, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPCgenproof1.html#compare_sint_spec">compare_sint_spec</a> [lemma, in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.PPC.html#compare_uint">compare_uint</a> [definition, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPCgenproof1.html#compare_uint_spec">compare_uint_spec</a> [lemma, in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.AST.html#comparison">comparison</a> [inductive, in <a href="backend.AST.html">backend.AST</a>]<br/>
-<a href="backend.Cminorgen.html#compilenv">compilenv</a> [definition, in <a href="backend.Cminorgen.html">backend.Cminorgen</a>]<br/>
-<a href="backend.Cminor.html#condexpr">condexpr</a> [inductive, in <a href="backend.Cminor.html">backend.Cminor</a>]<br/>
-<a href="backend.Cmconstr.html#condexpr_of_expr">condexpr_of_expr</a> [definition, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Op.html#condition">condition</a> [inductive, in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Cmconstr.html#conditionalexpr">conditionalexpr</a> [definition, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Constprop.html#cond_strength_reduction">cond_strength_reduction</a> [definition, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#cond_strength_reduction_cases">cond_strength_reduction_cases</a> [inductive, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constpropproof.html#cond_strength_reduction_correct">cond_strength_reduction_correct</a> [lemma, in <a href="backend.Constpropproof.html">backend.Constpropproof</a>]<br/>
-<a href="backend.Constprop.html#cond_strength_reduction_match">cond_strength_reduction_match</a> [definition, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.RTLtyping.html#consistent">consistent</a> [definition, in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.RTLtyping.html#consistent_not_eq">consistent_not_eq</a> [lemma, in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.PPC.html#constant">constant</a> [inductive, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.Constprop.html">Constprop</a> [library]<br/>
-<a href="backend.Constpropproof.html">Constpropproof</a> [library]<br/>
-<a href="backend.PPC.html#const_high">const_high</a> [definition, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#const_low">const_low</a> [definition, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.Parallelmove.html#cons_replace">cons_replace</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.LTL.html#Cont">Cont</a> [constructor, in <a href="backend.LTL.html">backend.LTL</a>]<br/>
-<a href="backend.Mem.html#Cont">Cont</a> [constructor, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#content">content</a> [inductive, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#contentmap">contentmap</a> [definition, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#contentmap_agree">contentmap_agree</a> [definition, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#contentmap_inject">contentmap_inject</a> [definition, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#contentmap_inject_incr">contentmap_inject_incr</a> [lemma, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#content_inject">content_inject</a> [inductive, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#content_inject_cont">content_inject_cont</a> [constructor, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#content_inject_datum16">content_inject_datum16</a> [constructor, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#content_inject_datum32">content_inject_datum32</a> [constructor, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#content_inject_datum64">content_inject_datum64</a> [constructor, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#content_inject_datum8">content_inject_datum8</a> [constructor, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#content_inject_incr">content_inject_incr</a> [lemma, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#content_inject_undef">content_inject_undef</a> [constructor, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Linearizeproof.html#cont_for_outcome">cont_for_outcome</a> [inductive, in <a href="backend.Linearizeproof.html">backend.Linearizeproof</a>]<br/>
-<a href="backend.Conventions.html">Conventions</a> [library]<br/>
-<a href="lib.Coqlib.html">Coqlib</a> [library]<br/>
-<a href="backend.Coloringproof.html#correct_alloc_instr">correct_alloc_instr</a> [definition, in <a href="backend.Coloringproof.html">backend.Coloringproof</a>]<br/>
-<a href="backend.Coloringproof.html#correct_interf_alloc_instr">correct_interf_alloc_instr</a> [lemma, in <a href="backend.Coloringproof.html">backend.Coloringproof</a>]<br/>
-<a href="backend.Coloringproof.html#correct_interf_instr">correct_interf_instr</a> [definition, in <a href="backend.Coloringproof.html">backend.Coloringproof</a>]<br/>
-<a href="backend.Coloringproof.html#correct_interf_instr_incl">correct_interf_instr_incl</a> [lemma, in <a href="backend.Coloringproof.html">backend.Coloringproof</a>]<br/>
-<a href="backend.PPC.html#crbit">crbit</a> [inductive, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPCgen.html#crbit_for_cond">crbit_for_cond</a> [definition, in <a href="backend.PPCgen.html">backend.PPCgen</a>]<br/>
-<a href="backend.PPCgen.html#crbit_for_fcmp">crbit_for_fcmp</a> [definition, in <a href="backend.PPCgen.html">backend.PPCgen</a>]<br/>
-<a href="backend.PPCgen.html#crbit_for_icmp">crbit_for_icmp</a> [definition, in <a href="backend.PPCgen.html">backend.PPCgen</a>]<br/>
-<a href="backend.PPC.html#CRbit_0">CRbit_0</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#CRbit_1">CRbit_1</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#CRbit_2">CRbit_2</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#CRbit_3">CRbit_3</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#CR0_0">CR0_0</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#CR0_1">CR0_1</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#CR0_2">CR0_2</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#CR0_3">CR0_3</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.CSE.html">CSE</a> [library]<br/>
-<a href="backend.CSEproof.html">CSEproof</a> [library]<br/>
-<a href="backend.Csharpminor.html">Csharpminor</a> [library]<br/>
-<a href="backend.Constprop.html#csr_case1">csr_case1</a> [constructor, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#csr_case2">csr_case2</a> [constructor, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#csr_default">csr_default</a> [constructor, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.PPC.html#Csymbol_high_signed">Csymbol_high_signed</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Csymbol_high_unsigned">Csymbol_high_unsigned</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Csymbol_low_signed">Csymbol_low_signed</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Csymbol_low_unsigned">Csymbol_low_unsigned</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#CTR">CTR</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<br/><br/><a name="global_D"></a><h2>D </h2>
-<a href="backend.Constprop.html#D">D</a> [module, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Kildall.html#Dataflow_Solver">Dataflow_Solver</a> [module, in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Kildall.html#DATAFLOW_SOLVER">DATAFLOW_SOLVER</a> [module, in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Mem.html#Datum16">Datum16</a> [constructor, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#Datum32">Datum32</a> [constructor, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#Datum64">Datum64</a> [constructor, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#Datum8">Datum8</a> [constructor, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.RTLtyping.html#decode">decode</a> [definition, in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.Parallelmove.html#def">def</a> [definition, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.RTLtyping.html#definite">definite</a> [definition, in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.RTLtyping.html#definite_included">definite_included</a> [lemma, in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.Conventions.html#destroyed_at_call">destroyed_at_call</a> [definition, in <a href="backend.Conventions.html">backend.Conventions</a>]<br/>
-<a href="backend.Conventions.html#destroyed_at_call_regs">destroyed_at_call_regs</a> [definition, in <a href="backend.Conventions.html">backend.Conventions</a>]<br/>
-<a href="backend.Locations.html#diff">diff</a> [definition, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Parallelmove.html#diff_dec">diff_dec</a> [definition, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Locations.html#diff_not_eq">diff_not_eq</a> [lemma, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#diff_sym">diff_sym</a> [lemma, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Kildall.html#discard_top_worklist_invariant">discard_top_worklist_invariant</a> [lemma, in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Parallelmove.html#disc1">disc1</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#disc2">disc2</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Locations.html#disjoint">disjoint</a> [definition, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#disjoint_cons_left">disjoint_cons_left</a> [lemma, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#disjoint_cons_right">disjoint_cons_right</a> [lemma, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#disjoint_notin">disjoint_notin</a> [lemma, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#disjoint_sym">disjoint_sym</a> [lemma, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Parallelmove.html#disjoint_tmp__noTmp">disjoint_tmp__noTmp</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Allocproof_aux.html#dis_dsttmp1_pnilnil">dis_dsttmp1_pnilnil</a> [lemma, in <a href="backend.Allocproof_aux.html">backend.Allocproof_aux</a>]<br/>
-<a href="backend.Allocproof_aux.html#dis_srctmp1_pnilnil">dis_srctmp1_pnilnil</a> [lemma, in <a href="backend.Allocproof_aux.html">backend.Allocproof_aux</a>]<br/>
-<a href="lib.Floats.html#div">div</a> [axiom, in <a href="lib.Floats.html">lib.Floats</a>]<br/>
-<a href="backend.Values.html#divf">divf</a> [definition, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Cmconstr.html#divf">divf</a> [definition, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#divs">divs</a> [definition, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="lib.Integers.html#divs">divs</a> [definition, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Values.html#divs">divs</a> [definition, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="lib.Integers.html#divs_pow2">divs_pow2</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Values.html#divs_pow2">divs_pow2</a> [lemma, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Cmconstr.html#divu">divu</a> [definition, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Values.html#divu">divu</a> [definition, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="lib.Integers.html#divu">divu</a> [definition, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Cmconstr.html#divu_cases">divu_cases</a> [inductive, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#divu_case1">divu_case1</a> [constructor, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#divu_default">divu_default</a> [constructor, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#divu_match">divu_match</a> [definition, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Values.html#divu_pow2">divu_pow2</a> [lemma, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="lib.Integers.html#divu_pow2">divu_pow2</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Allocproof_aux.html#Done_notmp1src_inv">Done_notmp1src_inv</a> [lemma, in <a href="backend.Allocproof_aux.html">backend.Allocproof_aux</a>]<br/>
-<a href="backend.Allocproof_aux.html#Done_notmp1src_invf">Done_notmp1src_invf</a> [lemma, in <a href="backend.Allocproof_aux.html">backend.Allocproof_aux</a>]<br/>
-<a href="backend.Allocproof_aux.html#Done_notmp1src_invpp">Done_notmp1src_invpp</a> [lemma, in <a href="backend.Allocproof_aux.html">backend.Allocproof_aux</a>]<br/>
-<a href="backend.Allocproof_aux.html#Done_notmp1src_res">Done_notmp1src_res</a> [lemma, in <a href="backend.Allocproof_aux.html">backend.Allocproof_aux</a>]<br/>
-<a href="backend.Allocproof_aux.html#Done_notmp1_inv">Done_notmp1_inv</a> [lemma, in <a href="backend.Allocproof_aux.html">backend.Allocproof_aux</a>]<br/>
-<a href="backend.Allocproof_aux.html#Done_notmp1_invf">Done_notmp1_invf</a> [lemma, in <a href="backend.Allocproof_aux.html">backend.Allocproof_aux</a>]<br/>
-<a href="backend.Allocproof_aux.html#Done_notmp1_invpp">Done_notmp1_invpp</a> [lemma, in <a href="backend.Allocproof_aux.html">backend.Allocproof_aux</a>]<br/>
-<a href="backend.Allocproof_aux.html#Done_notmp1_res">Done_notmp1_res</a> [lemma, in <a href="backend.Allocproof_aux.html">backend.Allocproof_aux</a>]<br/>
-<a href="backend.Allocproof_aux.html#Done_notmp3_inv">Done_notmp3_inv</a> [lemma, in <a href="backend.Allocproof_aux.html">backend.Allocproof_aux</a>]<br/>
-<a href="backend.Allocproof_aux.html#Done_notmp3_invf">Done_notmp3_invf</a> [lemma, in <a href="backend.Allocproof_aux.html">backend.Allocproof_aux</a>]<br/>
-<a href="backend.Allocproof_aux.html#Done_notmp3_invpp">Done_notmp3_invpp</a> [lemma, in <a href="backend.Allocproof_aux.html">backend.Allocproof_aux</a>]<br/>
-<a href="backend.Allocproof_aux.html#Done_notmp3_res">Done_notmp3_res</a> [lemma, in <a href="backend.Allocproof_aux.html">backend.Allocproof_aux</a>]<br/>
-<a href="backend.Allocproof_aux.html#Done_well_formed">Done_well_formed</a> [definition, in <a href="backend.Allocproof_aux.html">backend.Allocproof_aux</a>]<br/>
-<a href="backend.Conventions.html#drop1">drop1</a> [definition, in <a href="backend.Conventions.html">backend.Conventions</a>]<br/>
-<a href="backend.Conventions.html#drop2">drop2</a> [definition, in <a href="backend.Conventions.html">backend.Conventions</a>]<br/>
-<a href="backend.Kildall.html#DS">DS</a> [module, in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Constprop.html#DS">DS</a> [module, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Linearize.html#DS">DS</a> [module, in <a href="backend.Linearize.html">backend.Linearize</a>]<br/>
-<a href="backend.Allocation.html#DS">DS</a> [module, in <a href="backend.Allocation.html">backend.Allocation</a>]<br/>
-<a href="backend.Parallelmove.html#dstep">dstep</a> [inductive, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#dstepp">dstepp</a> [inductive, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#dstepp_refl">dstepp_refl</a> [constructor, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#dstepp_sameExec">dstepp_sameExec</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#dstepp_stepp">dstepp_stepp</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#dstepp_trans">dstepp_trans</a> [constructor, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#dstep_inv">dstep_inv</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#dstep_inv_getdst">dstep_inv_getdst</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#dstep_nop">dstep_nop</a> [constructor, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#dstep_pop">dstep_pop</a> [constructor, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#dstep_pop_loop">dstep_pop_loop</a> [constructor, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#dstep_push">dstep_push</a> [constructor, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#dstep_start">dstep_start</a> [constructor, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#dstep_step">dstep_step</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Allocproof_aux.html#dst_tmp2_res">dst_tmp2_res</a> [lemma, in <a href="backend.Allocproof_aux.html">backend.Allocproof_aux</a>]<br/>
-<a href="backend.Allocproof_aux.html#dst_tmp2_step">dst_tmp2_step</a> [lemma, in <a href="backend.Allocproof_aux.html">backend.Allocproof_aux</a>]<br/>
-<a href="backend.Allocproof_aux.html#dst_tmp2_stepf">dst_tmp2_stepf</a> [lemma, in <a href="backend.Allocproof_aux.html">backend.Allocproof_aux</a>]<br/>
-<a href="backend.Allocproof_aux.html#dst_tmp2_stepp">dst_tmp2_stepp</a> [lemma, in <a href="backend.Allocproof_aux.html">backend.Allocproof_aux</a>]<br/>
-<br/><br/><a name="global_E"></a><h2>E </h2>
-<a href="backend.Csharpminor.html#Eaddrof">Eaddrof</a> [constructor, in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Cminor.html#Eassign">Eassign</a> [constructor, in <a href="backend.Cminor.html">backend.Cminor</a>]<br/>
-<a href="backend.Csharpminor.html#Eassign">Eassign</a> [constructor, in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Csharpminor.html#Ecall">Ecall</a> [constructor, in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Cminor.html#Ecall">Ecall</a> [constructor, in <a href="backend.Cminor.html">backend.Cminor</a>]<br/>
-<a href="backend.Csharpminor.html#Econdition">Econdition</a> [constructor, in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Cminor.html#Econdition">Econdition</a> [constructor, in <a href="backend.Cminor.html">backend.Cminor</a>]<br/>
-<a href="backend.Cminor.html#Econs">Econs</a> [constructor, in <a href="backend.Cminor.html">backend.Cminor</a>]<br/>
-<a href="backend.Csharpminor.html#Econs">Econs</a> [constructor, in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="lib.union_find.html#ELEMENT">ELEMENT</a> [module, in <a href="lib.union_find.html">lib.union_find</a>]<br/>
-<a href="lib.Sets.html#elements">elements</a> [definition, in <a href="lib.Sets.html">lib.Sets</a>]<br/>
-<a href="lib.Maps.html#elements">elements</a> [definition, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#elements_complete">elements_complete</a> [lemma, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Sets.html#elements_complete">elements_complete</a> [lemma, in <a href="lib.Sets.html">lib.Sets</a>]<br/>
-<a href="lib.Maps.html#elements_correct">elements_correct</a> [lemma, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Sets.html#elements_correct">elements_correct</a> [lemma, in <a href="lib.Sets.html">lib.Sets</a>]<br/>
-<a href="lib.Maps.html#elements_keys_norepet">elements_keys_norepet</a> [lemma, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="backend.Csharpminor.html#Elet">Elet</a> [constructor, in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Cminor.html#Elet">Elet</a> [constructor, in <a href="backend.Cminor.html">backend.Cminor</a>]<br/>
-<a href="backend.Cminor.html#Eletvar">Eletvar</a> [constructor, in <a href="backend.Cminor.html">backend.Cminor</a>]<br/>
-<a href="backend.Csharpminor.html#Eletvar">Eletvar</a> [constructor, in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Cminor.html#Eload">Eload</a> [constructor, in <a href="backend.Cminor.html">backend.Cminor</a>]<br/>
-<a href="backend.Csharpminor.html#Eload">Eload</a> [constructor, in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="lib.Maps.html#elt">elt</a> [definition, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="backend.RTLtyping.html#elt">elt</a> [definition, in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="lib.Sets.html#elt">elt</a> [definition, in <a href="lib.Sets.html">lib.Sets</a>]<br/>
-<a href="lib.union_find.html#elt">elt</a> [definition, in <a href="lib.union_find.html">lib.union_find</a>]<br/>
-<a href="lib.union_find.html#elt">elt</a> [definition, in <a href="lib.union_find.html">lib.union_find</a>]<br/>
-<a href="lib.union_find.html#elt">elt</a> [definition, in <a href="lib.union_find.html">lib.union_find</a>]<br/>
-<a href="lib.Maps.html#elt">elt</a> [definition, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#elt">elt</a> [definition, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#elt">elt</a> [definition, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#elt_eq">elt_eq</a> [definition, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#elt_eq">elt_eq</a> [definition, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#elt_eq">elt_eq</a> [definition, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#elt_eq">elt_eq</a> [definition, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#EMap">EMap</a> [module, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Sets.html#empty">empty</a> [definition, in <a href="lib.Sets.html">lib.Sets</a>]<br/>
-<a href="lib.Maps.html#empty">empty</a> [definition, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.union_find.html#empty">empty</a> [definition, in <a href="lib.union_find.html">lib.union_find</a>]<br/>
-<a href="backend.RTLtyping.html#empty">empty</a> [definition, in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.Globalenvs.html#empty">empty</a> [definition, in <a href="backend.Globalenvs.html">backend.Globalenvs</a>]<br/>
-<a href="backend.Mem.html#empty">empty</a> [definition, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#empty_block">empty_block</a> [definition, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Csharpminor.html#empty_env">empty_env</a> [definition, in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Machabstr.html#empty_frame">empty_frame</a> [definition, in <a href="backend.Machabstr.html">backend.Machabstr</a>]<br/>
-<a href="backend.InterfGraph.html#empty_graph">empty_graph</a> [definition, in <a href="backend.InterfGraph.html">backend.InterfGraph</a>]<br/>
-<a href="backend.CSE.html#empty_numbering">empty_numbering</a> [definition, in <a href="backend.CSE.html">backend.CSE</a>]<br/>
-<a href="backend.CSE.html#empty_numbering_satisfiable">empty_numbering_satisfiable</a> [lemma, in <a href="backend.CSE.html">backend.CSE</a>]<br/>
-<a href="backend.RTLtyping.html#encode">encode</a> [definition, in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.RTLtyping.html#encode_decode">encode_decode</a> [lemma, in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.RTLtyping.html#encode_injective">encode_injective</a> [lemma, in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.Csharpminor.html#Enil">Enil</a> [constructor, in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Cminor.html#Enil">Enil</a> [constructor, in <a href="backend.Cminor.html">backend.Cminor</a>]<br/>
-<a href="backend.Allocproof.html#entrypoint_function_translated">entrypoint_function_translated</a> [lemma, in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.Linearize.html#enumerate">enumerate</a> [definition, in <a href="backend.Linearize.html">backend.Linearize</a>]<br/>
-<a href="backend.Linearizeproof.html#enumerate_complete">enumerate_complete</a> [lemma, in <a href="backend.Linearizeproof.html">backend.Linearizeproof</a>]<br/>
-<a href="backend.Linearizeproof.html#enumerate_head">enumerate_head</a> [lemma, in <a href="backend.Linearizeproof.html">backend.Linearizeproof</a>]<br/>
-<a href="backend.Linearizeproof.html#enumerate_norepet">enumerate_norepet</a> [lemma, in <a href="backend.Linearizeproof.html">backend.Linearizeproof</a>]<br/>
-<a href="backend.Csharpminor.html#env">env</a> [definition, in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Parallelmove.html#Env">Env</a> [definition, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Cminor.html#env">env</a> [definition, in <a href="backend.Cminor.html">backend.Cminor</a>]<br/>
-<a href="backend.Csharpminor.html#Eop">Eop</a> [constructor, in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Cminor.html#Eop">Eop</a> [constructor, in <a href="backend.Cminor.html">backend.Cminor</a>]<br/>
-<a href="backend.Constprop.html#eq">eq</a> [lemma, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Mach.html#eq">eq</a> [definition, in <a href="backend.Mach.html">backend.Mach</a>]<br/>
-<a href="lib.Ordered.html#eq">eq</a> [definition, in <a href="lib.Ordered.html">lib.Ordered</a>]<br/>
-<a href="backend.RTLtyping.html#eq">eq</a> [definition, in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="lib.Lattice.html#eq">eq</a> [lemma, in <a href="lib.Lattice.html">lib.Lattice</a>]<br/>
-<a href="lib.Sets.html#eq">eq</a> [lemma, in <a href="lib.Sets.html">lib.Sets</a>]<br/>
-<a href="backend.CSEproof.html#eq">eq</a> [definition, in <a href="backend.CSEproof.html">backend.CSEproof</a>]<br/>
-<a href="lib.Lattice.html#eq">eq</a> [lemma, in <a href="lib.Lattice.html">lib.Lattice</a>]<br/>
-<a href="lib.Lattice.html#eq">eq</a> [lemma, in <a href="lib.Lattice.html">lib.Lattice</a>]<br/>
-<a href="backend.Locations.html#eq">eq</a> [lemma, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="lib.Maps.html#eq">eq</a> [definition, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#eq">eq</a> [lemma, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="backend.Locations.html#eq">eq</a> [definition, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="lib.Ordered.html#eq">eq</a> [definition, in <a href="lib.Ordered.html">lib.Ordered</a>]<br/>
-<a href="backend.Registers.html#eq">eq</a> [definition, in <a href="backend.Registers.html">backend.Registers</a>]<br/>
-<a href="lib.Maps.html#eq">eq</a> [lemma, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Ordered.html#eq">eq</a> [definition, in <a href="lib.Ordered.html">lib.Ordered</a>]<br/>
-<a href="backend.PPC.html#eq">eq</a> [definition, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="lib.Integers.html#eq">eq</a> [definition, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#eqm">eqm</a> [definition, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#eqmod">eqmod</a> [definition, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#eqmod_add">eqmod_add</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#eqmod_mod">eqmod_mod</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#eqmod_mod_eq">eqmod_mod_eq</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#eqmod_mult">eqmod_mult</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#eqmod_neg">eqmod_neg</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#eqmod_refl">eqmod_refl</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#eqmod_refl2">eqmod_refl2</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#eqmod_small_eq">eqmod_small_eq</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#eqmod_sub">eqmod_sub</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#eqmod_sym">eqmod_sym</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#eqmod_trans">eqmod_trans</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#eqmod_256_unsigned_repr">eqmod_256_unsigned_repr</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#eqmod_65536_unsigned_repr">eqmod_65536_unsigned_repr</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#eqm_add">eqm_add</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#eqm_mult">eqm_mult</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#eqm_neg">eqm_neg</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#eqm_refl">eqm_refl</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#eqm_refl2">eqm_refl2</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#eqm_samerepr">eqm_samerepr</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#eqm_signed_unsigned">eqm_signed_unsigned</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#eqm_small_eq">eqm_small_eq</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#eqm_sub">eqm_sub</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#eqm_sym">eqm_sym</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#eqm_trans">eqm_trans</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#eqm_unsigned_repr">eqm_unsigned_repr</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#eqm_unsigned_repr_l">eqm_unsigned_repr_l</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#eqm_unsigned_repr_r">eqm_unsigned_repr_r</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Maps.html#EQUALITY_TYPE">EQUALITY_TYPE</a> [module, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="backend.RTLtyping.html#equal_eq">equal_eq</a> [lemma, in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="lib.Integers.html#equal_on_range">equal_on_range</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.CSEproof.html#equation_evals_to_holds_1">equation_evals_to_holds_1</a> [lemma, in <a href="backend.CSEproof.html">backend.CSEproof</a>]<br/>
-<a href="backend.CSEproof.html#equation_evals_to_holds_2">equation_evals_to_holds_2</a> [lemma, in <a href="backend.CSEproof.html">backend.CSEproof</a>]<br/>
-<a href="backend.CSE.html#equation_holds">equation_holds</a> [definition, in <a href="backend.CSE.html">backend.CSE</a>]<br/>
-<a href="backend.Values.html#eq_block">eq_block</a> [definition, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="lib.Integers.html#eq_dec">eq_dec</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Floats.html#eq_dec">eq_dec</a> [axiom, in <a href="lib.Floats.html">lib.Floats</a>]<br/>
-<a href="lib.Integers.html#eq_false">eq_false</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.CSE.html#eq_list_valnum">eq_list_valnum</a> [definition, in <a href="backend.CSE.html">backend.CSE</a>]<br/>
-<a href="lib.Ordered.html#eq_refl">eq_refl</a> [lemma, in <a href="lib.Ordered.html">lib.Ordered</a>]<br/>
-<a href="lib.Ordered.html#eq_refl">eq_refl</a> [lemma, in <a href="lib.Ordered.html">lib.Ordered</a>]<br/>
-<a href="lib.Ordered.html#eq_refl">eq_refl</a> [lemma, in <a href="lib.Ordered.html">lib.Ordered</a>]<br/>
-<a href="backend.CSE.html#eq_rhs">eq_rhs</a> [definition, in <a href="backend.CSE.html">backend.CSE</a>]<br/>
-<a href="lib.Integers.html#eq_spec">eq_spec</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Ordered.html#eq_sym">eq_sym</a> [lemma, in <a href="lib.Ordered.html">lib.Ordered</a>]<br/>
-<a href="lib.Ordered.html#eq_sym">eq_sym</a> [lemma, in <a href="lib.Ordered.html">lib.Ordered</a>]<br/>
-<a href="lib.Integers.html#eq_sym">eq_sym</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Ordered.html#eq_sym">eq_sym</a> [lemma, in <a href="lib.Ordered.html">lib.Ordered</a>]<br/>
-<a href="lib.Ordered.html#eq_trans">eq_trans</a> [lemma, in <a href="lib.Ordered.html">lib.Ordered</a>]<br/>
-<a href="lib.Ordered.html#eq_trans">eq_trans</a> [lemma, in <a href="lib.Ordered.html">lib.Ordered</a>]<br/>
-<a href="lib.Ordered.html#eq_trans">eq_trans</a> [lemma, in <a href="lib.Ordered.html">lib.Ordered</a>]<br/>
-<a href="lib.Integers.html#eq_true">eq_true</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.CSE.html#eq_valnum">eq_valnum</a> [definition, in <a href="backend.CSE.html">backend.CSE</a>]<br/>
-<a href="lib.Floats.html#eq_zero_false">eq_zero_false</a> [axiom, in <a href="lib.Floats.html">lib.Floats</a>]<br/>
-<a href="lib.Floats.html#eq_zero_true">eq_zero_true</a> [axiom, in <a href="lib.Floats.html">lib.Floats</a>]<br/>
-<a href="backend.RTLgen.html#Error">Error</a> [constructor, in <a href="backend.RTLgen.html">backend.RTLgen</a>]<br/>
-<a href="backend.RTLtyping.html#error">error</a> [definition, in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.RTLgen.html#error">error</a> [definition, in <a href="backend.RTLgen.html">backend.RTLgen</a>]<br/>
-<a href="backend.PPC.html#Error">Error</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.RTLtyping.html#error_inconsistent">error_inconsistent</a> [lemma, in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.Cminor.html#Estore">Estore</a> [constructor, in <a href="backend.Cminor.html">backend.Cminor</a>]<br/>
-<a href="backend.Csharpminor.html#Estore">Estore</a> [constructor, in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_absfloat">eval_absfloat</a> [lemma, in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_add">eval_add</a> [lemma, in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_addf">eval_addf</a> [lemma, in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_addimm">eval_addimm</a> [lemma, in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_addimm_ptr">eval_addimm_ptr</a> [lemma, in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_addressing">eval_addressing</a> [lemma, in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Op.html#eval_addressing">eval_addressing</a> [definition, in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Op.html#eval_addressing_preserved">eval_addressing_preserved</a> [lemma, in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Op.html#eval_addressing_total">eval_addressing_total</a> [definition, in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Op.html#eval_addressing_weaken">eval_addressing_weaken</a> [lemma, in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_add_ptr">eval_add_ptr</a> [lemma, in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_add_ptr_2">eval_add_ptr_2</a> [lemma, in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_and">eval_and</a> [lemma, in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_andimm">eval_andimm</a> [lemma, in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_base_condition_of_expr">eval_base_condition_of_expr</a> [lemma, in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_cast16signed">eval_cast16signed</a> [lemma, in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_cast16unsigned">eval_cast16unsigned</a> [lemma, in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_cast8signed">eval_cast8signed</a> [lemma, in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_cast8unsigned">eval_cast8unsigned</a> [lemma, in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_cmp">eval_cmp</a> [lemma, in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_cmpf">eval_cmpf</a> [lemma, in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_cmpu">eval_cmpu</a> [lemma, in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_cmp_null_l">eval_cmp_null_l</a> [lemma, in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_cmp_null_r">eval_cmp_null_r</a> [lemma, in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_cmp_ptr">eval_cmp_ptr</a> [lemma, in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Op.html#eval_compare_null">eval_compare_null</a> [definition, in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Csharpminor.html#eval_compare_null">eval_compare_null</a> [definition, in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Op.html#eval_compare_null_weaken">eval_compare_null_weaken</a> [lemma, in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Op.html#eval_condition">eval_condition</a> [definition, in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_conditionalexpr_false">eval_conditionalexpr_false</a> [lemma, in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_conditionalexpr_true">eval_conditionalexpr_true</a> [lemma, in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_condition_of_expr">eval_condition_of_expr</a> [lemma, in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Op.html#eval_condition_total">eval_condition_total</a> [definition, in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Op.html#eval_condition_total_is_bool">eval_condition_total_is_bool</a> [lemma, in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Op.html#eval_condition_weaken">eval_condition_weaken</a> [lemma, in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_divf">eval_divf</a> [lemma, in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_divs">eval_divs</a> [lemma, in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_divu">eval_divu</a> [lemma, in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_divu_base">eval_divu_base</a> [lemma, in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Csharpminor.html#eval_Evar">eval_Evar</a> [constructor, in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Cminor.html#eval_Evar">eval_Evar</a> [constructor, in <a href="backend.Cminor.html">backend.Cminor</a>]<br/>
-<a href="backend.Csharpminor.html#eval_expr">eval_expr</a> [inductive, in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Cminor.html#eval_expr">eval_expr</a> [inductive, in <a href="backend.Cminor.html">backend.Cminor</a>]<br/>
-<a href="backend.Cminorgenproof.html#eval_exprlist_prop">eval_exprlist_prop</a> [definition, in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#eval_expr_prop">eval_expr_prop</a> [definition, in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_floatofint">eval_floatofint</a> [lemma, in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_floatofintu">eval_floatofintu</a> [lemma, in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#eval_funcall_prop">eval_funcall_prop</a> [definition, in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_intoffloat">eval_intoffloat</a> [lemma, in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_lift">eval_lift</a> [lemma, in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_lift_expr">eval_lift_expr</a> [lemma, in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_load">eval_load</a> [lemma, in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_mods">eval_mods</a> [lemma, in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_modu">eval_modu</a> [lemma, in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_mod_aux">eval_mod_aux</a> [lemma, in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_mul">eval_mul</a> [lemma, in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_mulf">eval_mulf</a> [lemma, in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_mulimm">eval_mulimm</a> [lemma, in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_mulimm_base">eval_mulimm_base</a> [lemma, in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Op.html#eval_negate_condition">eval_negate_condition</a> [lemma, in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_negfloat">eval_negfloat</a> [lemma, in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_negint">eval_negint</a> [lemma, in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_notbool">eval_notbool</a> [lemma, in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_notbool_base">eval_notbool_base</a> [lemma, in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_notint">eval_notint</a> [lemma, in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Op.html#eval_operation">eval_operation</a> [definition, in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Csharpminor.html#eval_operation">eval_operation</a> [definition, in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Op.html#eval_operation_preserved">eval_operation_preserved</a> [lemma, in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Op.html#eval_operation_total">eval_operation_total</a> [definition, in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Op.html#eval_operation_weaken">eval_operation_weaken</a> [lemma, in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_or">eval_or</a> [lemma, in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_rolm">eval_rolm</a> [lemma, in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_shl">eval_shl</a> [lemma, in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_shlimm">eval_shlimm</a> [lemma, in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_shr">eval_shr</a> [lemma, in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_shru">eval_shru</a> [lemma, in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_shruimm">eval_shruimm</a> [lemma, in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_singleoffloat">eval_singleoffloat</a> [lemma, in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Constprop.html#eval_static_condition">eval_static_condition</a> [definition, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_condition_cases">eval_static_condition_cases</a> [inductive, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_condition_case1">eval_static_condition_case1</a> [constructor, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_condition_case2">eval_static_condition_case2</a> [constructor, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_condition_case3">eval_static_condition_case3</a> [constructor, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_condition_case4">eval_static_condition_case4</a> [constructor, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_condition_case5">eval_static_condition_case5</a> [constructor, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_condition_case6">eval_static_condition_case6</a> [constructor, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_condition_case7">eval_static_condition_case7</a> [constructor, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_condition_case8">eval_static_condition_case8</a> [constructor, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constpropproof.html#eval_static_condition_correct">eval_static_condition_correct</a> [lemma, in <a href="backend.Constpropproof.html">backend.Constpropproof</a>]<br/>
-<a href="backend.Constprop.html#eval_static_condition_default">eval_static_condition_default</a> [constructor, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_condition_match">eval_static_condition_match</a> [definition, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_operation">eval_static_operation</a> [definition, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_operation_cases">eval_static_operation_cases</a> [inductive, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_operation_case1">eval_static_operation_case1</a> [constructor, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_operation_case11">eval_static_operation_case11</a> [constructor, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_operation_case12">eval_static_operation_case12</a> [constructor, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_operation_case13">eval_static_operation_case13</a> [constructor, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_operation_case14">eval_static_operation_case14</a> [constructor, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_operation_case15">eval_static_operation_case15</a> [constructor, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_operation_case16">eval_static_operation_case16</a> [constructor, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_operation_case17">eval_static_operation_case17</a> [constructor, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_operation_case18">eval_static_operation_case18</a> [constructor, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_operation_case19">eval_static_operation_case19</a> [constructor, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_operation_case2">eval_static_operation_case2</a> [constructor, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_operation_case20">eval_static_operation_case20</a> [constructor, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_operation_case21">eval_static_operation_case21</a> [constructor, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_operation_case22">eval_static_operation_case22</a> [constructor, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_operation_case23">eval_static_operation_case23</a> [constructor, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_operation_case24">eval_static_operation_case24</a> [constructor, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_operation_case25">eval_static_operation_case25</a> [constructor, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_operation_case26">eval_static_operation_case26</a> [constructor, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_operation_case27">eval_static_operation_case27</a> [constructor, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_operation_case28">eval_static_operation_case28</a> [constructor, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_operation_case29">eval_static_operation_case29</a> [constructor, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_operation_case3">eval_static_operation_case3</a> [constructor, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_operation_case30">eval_static_operation_case30</a> [constructor, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_operation_case31">eval_static_operation_case31</a> [constructor, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_operation_case32">eval_static_operation_case32</a> [constructor, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_operation_case33">eval_static_operation_case33</a> [constructor, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_operation_case34">eval_static_operation_case34</a> [constructor, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_operation_case35">eval_static_operation_case35</a> [constructor, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_operation_case36">eval_static_operation_case36</a> [constructor, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_operation_case37">eval_static_operation_case37</a> [constructor, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_operation_case38">eval_static_operation_case38</a> [constructor, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_operation_case39">eval_static_operation_case39</a> [constructor, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_operation_case4">eval_static_operation_case4</a> [constructor, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_operation_case40">eval_static_operation_case40</a> [constructor, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_operation_case41">eval_static_operation_case41</a> [constructor, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_operation_case42">eval_static_operation_case42</a> [constructor, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_operation_case43">eval_static_operation_case43</a> [constructor, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_operation_case44">eval_static_operation_case44</a> [constructor, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_operation_case45">eval_static_operation_case45</a> [constructor, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_operation_case46">eval_static_operation_case46</a> [constructor, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_operation_case47">eval_static_operation_case47</a> [constructor, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_operation_case6">eval_static_operation_case6</a> [constructor, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_operation_case7">eval_static_operation_case7</a> [constructor, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_operation_case8">eval_static_operation_case8</a> [constructor, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_operation_case9">eval_static_operation_case9</a> [constructor, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constpropproof.html#eval_static_operation_correct">eval_static_operation_correct</a> [lemma, in <a href="backend.Constpropproof.html">backend.Constpropproof</a>]<br/>
-<a href="backend.Constprop.html#eval_static_operation_default">eval_static_operation_default</a> [constructor, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_operation_match">eval_static_operation_match</a> [definition, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_store">eval_store</a> [lemma, in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_sub">eval_sub</a> [lemma, in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_subf">eval_subf</a> [lemma, in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_sub_ptr_int">eval_sub_ptr_int</a> [lemma, in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_sub_ptr_ptr">eval_sub_ptr_ptr</a> [lemma, in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_xor">eval_xor</a> [lemma, in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cminor.html#Evar">Evar</a> [constructor, in <a href="backend.Cminor.html">backend.Cminor</a>]<br/>
-<a href="backend.Csharpminor.html#Evar">Evar</a> [constructor, in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Parallelmove.html#exec">exec</a> [definition, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.LTL.html#exec_Bgetstack">exec_Bgetstack</a> [constructor, in <a href="backend.LTL.html">backend.LTL</a>]<br/>
-<a href="backend.Tunnelingproof.html#exec_blocks_Bgoto_inv">exec_blocks_Bgoto_inv</a> [lemma, in <a href="backend.Tunnelingproof.html">backend.Tunnelingproof</a>]<br/>
-<a href="backend.LTL.html#exec_blocks_extends">exec_blocks_extends</a> [lemma, in <a href="backend.LTL.html">backend.LTL</a>]<br/>
-<a href="backend.Linearizeproof.html#exec_blocks_prop">exec_blocks_prop</a> [definition, in <a href="backend.Linearizeproof.html">backend.Linearizeproof</a>]<br/>
-<a href="backend.Tunnelingproof.html#exec_blocks_prop">exec_blocks_prop</a> [definition, in <a href="backend.Tunnelingproof.html">backend.Tunnelingproof</a>]<br/>
-<a href="backend.Linearizeproof.html#exec_blocks_valid_outcome">exec_blocks_valid_outcome</a> [lemma, in <a href="backend.Linearizeproof.html">backend.Linearizeproof</a>]<br/>
-<a href="backend.Tunnelingproof.html#exec_block_Bgoto_inv">exec_block_Bgoto_inv</a> [lemma, in <a href="backend.Tunnelingproof.html">backend.Tunnelingproof</a>]<br/>
-<a href="backend.Linearizeproof.html#exec_block_prop">exec_block_prop</a> [definition, in <a href="backend.Linearizeproof.html">backend.Linearizeproof</a>]<br/>
-<a href="backend.Tunnelingproof.html#exec_block_prop">exec_block_prop</a> [definition, in <a href="backend.Tunnelingproof.html">backend.Tunnelingproof</a>]<br/>
-<a href="backend.Machabstr2mach.html#exec_function_body_prop">exec_function_body_prop</a> [definition, in <a href="backend.Machabstr2mach.html">backend.Machabstr2mach</a>]<br/>
-<a href="backend.PPCgenproof.html#exec_function_body_prop">exec_function_body_prop</a> [definition, in <a href="backend.PPCgenproof.html">backend.PPCgenproof</a>]<br/>
-<a href="backend.Machtyping.html#exec_function_body_prop">exec_function_body_prop</a> [definition, in <a href="backend.Machtyping.html">backend.Machtyping</a>]<br/>
-<a href="backend.PPCgenproof.html#exec_function_body_prop_">exec_function_body_prop_</a> [lemma, in <a href="backend.PPCgenproof.html">backend.PPCgenproof</a>]<br/>
-<a href="backend.Machabstr2mach.html#exec_function_equiv">exec_function_equiv</a> [lemma, in <a href="backend.Machabstr2mach.html">backend.Machabstr2mach</a>]<br/>
-<a href="backend.Stackingproof.html#exec_function_prop">exec_function_prop</a> [definition, in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="backend.Machtyping.html#exec_function_prop">exec_function_prop</a> [definition, in <a href="backend.Machtyping.html">backend.Machtyping</a>]<br/>
-<a href="backend.PPCgenproof.html#exec_function_prop">exec_function_prop</a> [definition, in <a href="backend.PPCgenproof.html">backend.PPCgenproof</a>]<br/>
-<a href="backend.Constpropproof.html#exec_function_prop">exec_function_prop</a> [definition, in <a href="backend.Constpropproof.html">backend.Constpropproof</a>]<br/>
-<a href="backend.Linearizeproof.html#exec_function_prop">exec_function_prop</a> [definition, in <a href="backend.Linearizeproof.html">backend.Linearizeproof</a>]<br/>
-<a href="backend.Machabstr2mach.html#exec_function_prop">exec_function_prop</a> [definition, in <a href="backend.Machabstr2mach.html">backend.Machabstr2mach</a>]<br/>
-<a href="backend.CSEproof.html#exec_function_prop">exec_function_prop</a> [definition, in <a href="backend.CSEproof.html">backend.CSEproof</a>]<br/>
-<a href="backend.Tunnelingproof.html#exec_function_prop">exec_function_prop</a> [definition, in <a href="backend.Tunnelingproof.html">backend.Tunnelingproof</a>]<br/>
-<a href="backend.Allocproof.html#exec_function_prop">exec_function_prop</a> [definition, in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.PPCgenproof.html#exec_function_prop_">exec_function_prop_</a> [lemma, in <a href="backend.PPCgenproof.html">backend.PPCgenproof</a>]<br/>
-<a href="backend.RTLtyping.html#exec_function_subject_reduction">exec_function_subject_reduction</a> [definition, in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.Cmconstrproof.html#exec_ifthenelse_false">exec_ifthenelse_false</a> [lemma, in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#exec_ifthenelse_true">exec_ifthenelse_true</a> [lemma, in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.RTL.html#exec_Iload">exec_Iload</a> [constructor, in <a href="backend.RTL.html">backend.RTL</a>]<br/>
-<a href="backend.RTL.html#exec_Iload'">exec_Iload'</a> [lemma, in <a href="backend.RTL.html">backend.RTL</a>]<br/>
-<a href="backend.RTL.html#exec_Inop">exec_Inop</a> [constructor, in <a href="backend.RTL.html">backend.RTL</a>]<br/>
-<a href="backend.Machabstr.html#exec_instr">exec_instr</a> [inductive, in <a href="backend.Machabstr.html">backend.Machabstr</a>]<br/>
-<a href="backend.RTL.html#exec_instr">exec_instr</a> [inductive, in <a href="backend.RTL.html">backend.RTL</a>]<br/>
-<a href="backend.LTL.html#exec_instr">exec_instr</a> [inductive, in <a href="backend.LTL.html">backend.LTL</a>]<br/>
-<a href="backend.Linear.html#exec_instr">exec_instr</a> [inductive, in <a href="backend.Linear.html">backend.Linear</a>]<br/>
-<a href="backend.Mach.html#exec_instr">exec_instr</a> [inductive, in <a href="backend.Mach.html">backend.Mach</a>]<br/>
-<a href="backend.PPC.html#exec_instr">exec_instr</a> [definition, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.Tunnelingproof.html#exec_instrs_Bgoto_inv">exec_instrs_Bgoto_inv</a> [lemma, in <a href="backend.Tunnelingproof.html">backend.Tunnelingproof</a>]<br/>
-<a href="backend.RTLgenproof1.html#exec_instrs_extends">exec_instrs_extends</a> [lemma, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#exec_instrs_extends_rec">exec_instrs_extends_rec</a> [lemma, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.Stackingproof.html#exec_instrs_incl">exec_instrs_incl</a> [lemma, in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="backend.PPCgenproof.html#exec_instrs_incl">exec_instrs_incl</a> [lemma, in <a href="backend.PPCgenproof.html">backend.PPCgenproof</a>]<br/>
-<a href="backend.RTLgenproof1.html#exec_instrs_incr">exec_instrs_incr</a> [lemma, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.Machtyping.html#exec_instrs_link_invariant">exec_instrs_link_invariant</a> [lemma, in <a href="backend.Machtyping.html">backend.Machtyping</a>]<br/>
-<a href="backend.Allocproof_aux.html#exec_instrs_pmov">exec_instrs_pmov</a> [lemma, in <a href="backend.Allocproof_aux.html">backend.Allocproof_aux</a>]<br/>
-<a href="backend.RTL.html#exec_instrs_present">exec_instrs_present</a> [lemma, in <a href="backend.RTL.html">backend.RTL</a>]<br/>
-<a href="backend.Allocproof.html#exec_instrs_prop">exec_instrs_prop</a> [definition, in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.Tunnelingproof.html#exec_instrs_prop">exec_instrs_prop</a> [definition, in <a href="backend.Tunnelingproof.html">backend.Tunnelingproof</a>]<br/>
-<a href="backend.Machabstr2mach.html#exec_instrs_prop">exec_instrs_prop</a> [definition, in <a href="backend.Machabstr2mach.html">backend.Machabstr2mach</a>]<br/>
-<a href="backend.CSEproof.html#exec_instrs_prop">exec_instrs_prop</a> [definition, in <a href="backend.CSEproof.html">backend.CSEproof</a>]<br/>
-<a href="backend.Constpropproof.html#exec_instrs_prop">exec_instrs_prop</a> [definition, in <a href="backend.Constpropproof.html">backend.Constpropproof</a>]<br/>
-<a href="backend.Linearizeproof.html#exec_instrs_prop">exec_instrs_prop</a> [definition, in <a href="backend.Linearizeproof.html">backend.Linearizeproof</a>]<br/>
-<a href="backend.RTLgenproof1.html#exec_instr_extends">exec_instr_extends</a> [lemma, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#exec_instr_extends_rec">exec_instr_extends_rec</a> [lemma, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.PPCgenproof.html#exec_instr_incl">exec_instr_incl</a> [lemma, in <a href="backend.PPCgenproof.html">backend.PPCgenproof</a>]<br/>
-<a href="backend.Stackingproof.html#exec_instr_incl">exec_instr_incl</a> [lemma, in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="backend.RTLgenproof1.html#exec_instr_incr">exec_instr_incr</a> [lemma, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#exec_instr_in_s2">exec_instr_in_s2</a> [lemma, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.Machtyping.html#exec_instr_link_invariant">exec_instr_link_invariant</a> [lemma, in <a href="backend.Machtyping.html">backend.Machtyping</a>]<br/>
-<a href="backend.RTLgenproof1.html#exec_instr_not_halt">exec_instr_not_halt</a> [lemma, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTL.html#exec_instr_present">exec_instr_present</a> [lemma, in <a href="backend.RTL.html">backend.RTL</a>]<br/>
-<a href="backend.Allocproof.html#exec_instr_prop">exec_instr_prop</a> [definition, in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.Machabstr2mach.html#exec_instr_prop">exec_instr_prop</a> [definition, in <a href="backend.Machabstr2mach.html">backend.Machabstr2mach</a>]<br/>
-<a href="backend.Machtyping.html#exec_instr_prop">exec_instr_prop</a> [definition, in <a href="backend.Machtyping.html">backend.Machtyping</a>]<br/>
-<a href="backend.Constpropproof.html#exec_instr_prop">exec_instr_prop</a> [definition, in <a href="backend.Constpropproof.html">backend.Constpropproof</a>]<br/>
-<a href="backend.CSEproof.html#exec_instr_prop">exec_instr_prop</a> [definition, in <a href="backend.CSEproof.html">backend.CSEproof</a>]<br/>
-<a href="backend.Tunnelingproof.html#exec_instr_prop">exec_instr_prop</a> [definition, in <a href="backend.Tunnelingproof.html">backend.Tunnelingproof</a>]<br/>
-<a href="backend.Stackingproof.html#exec_instr_prop">exec_instr_prop</a> [definition, in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="backend.Linearizeproof.html#exec_instr_prop">exec_instr_prop</a> [definition, in <a href="backend.Linearizeproof.html">backend.Linearizeproof</a>]<br/>
-<a href="backend.PPCgenproof.html#exec_instr_prop">exec_instr_prop</a> [definition, in <a href="backend.PPCgenproof.html">backend.PPCgenproof</a>]<br/>
-<a href="backend.RTLtyping.html#exec_instr_subject_reduction">exec_instr_subject_reduction</a> [definition, in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.Allocproof_aux.html#exec_instr_update">exec_instr_update</a> [lemma, in <a href="backend.Allocproof_aux.html">backend.Allocproof_aux</a>]<br/>
-<a href="backend.RTL.html#exec_Iop">exec_Iop</a> [constructor, in <a href="backend.RTL.html">backend.RTL</a>]<br/>
-<a href="backend.RTL.html#exec_Iop'">exec_Iop'</a> [lemma, in <a href="backend.RTL.html">backend.RTL</a>]<br/>
-<a href="backend.Linear.html#exec_Lgetstack">exec_Lgetstack</a> [constructor, in <a href="backend.Linear.html">backend.Linear</a>]<br/>
-<a href="backend.PPCgenproof.html#exec_Mcall_prop">exec_Mcall_prop</a> [lemma, in <a href="backend.PPCgenproof.html">backend.PPCgenproof</a>]<br/>
-<a href="backend.PPCgenproof.html#exec_Mcond_false_prop">exec_Mcond_false_prop</a> [lemma, in <a href="backend.PPCgenproof.html">backend.PPCgenproof</a>]<br/>
-<a href="backend.PPCgenproof.html#exec_Mcond_true_prop">exec_Mcond_true_prop</a> [lemma, in <a href="backend.PPCgenproof.html">backend.PPCgenproof</a>]<br/>
-<a href="backend.Mach.html#exec_Mgetparam">exec_Mgetparam</a> [constructor, in <a href="backend.Mach.html">backend.Mach</a>]<br/>
-<a href="backend.PPCgenproof.html#exec_Mgetparam_prop">exec_Mgetparam_prop</a> [lemma, in <a href="backend.PPCgenproof.html">backend.PPCgenproof</a>]<br/>
-<a href="backend.Mach.html#exec_Mgetstack">exec_Mgetstack</a> [constructor, in <a href="backend.Mach.html">backend.Mach</a>]<br/>
-<a href="backend.Machabstr.html#exec_Mgetstack">exec_Mgetstack</a> [constructor, in <a href="backend.Machabstr.html">backend.Machabstr</a>]<br/>
-<a href="backend.Stackingproof.html#exec_Mgetstack'">exec_Mgetstack'</a> [lemma, in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="backend.PPCgenproof.html#exec_Mgetstack_prop">exec_Mgetstack_prop</a> [lemma, in <a href="backend.PPCgenproof.html">backend.PPCgenproof</a>]<br/>
-<a href="backend.PPCgenproof.html#exec_Mgoto_prop">exec_Mgoto_prop</a> [lemma, in <a href="backend.PPCgenproof.html">backend.PPCgenproof</a>]<br/>
-<a href="backend.Mach.html#exec_Mlabel">exec_Mlabel</a> [constructor, in <a href="backend.Mach.html">backend.Mach</a>]<br/>
-<a href="backend.Machabstr.html#exec_Mlabel">exec_Mlabel</a> [constructor, in <a href="backend.Machabstr.html">backend.Machabstr</a>]<br/>
-<a href="backend.PPCgenproof.html#exec_Mlabel_prop">exec_Mlabel_prop</a> [lemma, in <a href="backend.PPCgenproof.html">backend.PPCgenproof</a>]<br/>
-<a href="backend.PPCgenproof.html#exec_Mload_prop">exec_Mload_prop</a> [lemma, in <a href="backend.PPCgenproof.html">backend.PPCgenproof</a>]<br/>
-<a href="backend.PPCgenproof.html#exec_Mop_prop">exec_Mop_prop</a> [lemma, in <a href="backend.PPCgenproof.html">backend.PPCgenproof</a>]<br/>
-<a href="backend.Mach.html#exec_Msetstack">exec_Msetstack</a> [constructor, in <a href="backend.Mach.html">backend.Mach</a>]<br/>
-<a href="backend.Stackingproof.html#exec_Msetstack'">exec_Msetstack'</a> [lemma, in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="backend.PPCgenproof.html#exec_Msetstack_prop">exec_Msetstack_prop</a> [lemma, in <a href="backend.PPCgenproof.html">backend.PPCgenproof</a>]<br/>
-<a href="backend.PPCgenproof.html#exec_Mstore_prop">exec_Mstore_prop</a> [lemma, in <a href="backend.PPCgenproof.html">backend.PPCgenproof</a>]<br/>
-<a href="backend.Machabstr.html#exec_mutual_induction">exec_mutual_induction</a> [lemma, in <a href="backend.Machabstr.html">backend.Machabstr</a>]<br/>
-<a href="backend.PPC.html#exec_one">exec_one</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPCgenproof.html#exec_one_prop">exec_one_prop</a> [lemma, in <a href="backend.PPCgenproof.html">backend.PPCgenproof</a>]<br/>
-<a href="backend.Csharpminor.html#exec_program">exec_program</a> [definition, in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.LTL.html#exec_program">exec_program</a> [definition, in <a href="backend.LTL.html">backend.LTL</a>]<br/>
-<a href="backend.Cminor.html#exec_program">exec_program</a> [definition, in <a href="backend.Cminor.html">backend.Cminor</a>]<br/>
-<a href="backend.RTL.html#exec_program">exec_program</a> [definition, in <a href="backend.RTL.html">backend.RTL</a>]<br/>
-<a href="backend.Mach.html#exec_program">exec_program</a> [definition, in <a href="backend.Mach.html">backend.Mach</a>]<br/>
-<a href="backend.Machabstr.html#exec_program">exec_program</a> [definition, in <a href="backend.Machabstr.html">backend.Machabstr</a>]<br/>
-<a href="backend.Linear.html#exec_program">exec_program</a> [definition, in <a href="backend.Linear.html">backend.Linear</a>]<br/>
-<a href="backend.PPC.html#exec_program">exec_program</a> [definition, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.Machabstr2mach.html#exec_program_equiv">exec_program_equiv</a> [lemma, in <a href="backend.Machabstr2mach.html">backend.Machabstr2mach</a>]<br/>
-<a href="backend.PPC.html#exec_refl">exec_refl</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPCgenproof.html#exec_refl_prop">exec_refl_prop</a> [lemma, in <a href="backend.PPCgenproof.html">backend.PPCgenproof</a>]<br/>
-<a href="backend.RTL.html#exec_step">exec_step</a> [lemma, in <a href="backend.RTL.html">backend.RTL</a>]<br/>
-<a href="backend.PPC.html#exec_step">exec_step</a> [inductive, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#exec_steps">exec_steps</a> [inductive, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#exec_step_intro">exec_step_intro</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.Cminorgenproof.html#exec_stmtlist_prop">exec_stmtlist_prop</a> [definition, in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#exec_stmt_prop">exec_stmt_prop</a> [definition, in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.PPCgenproof1.html#exec_straight">exec_straight</a> [inductive, in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.PPCgenproof.html#exec_straight_exec_prop">exec_straight_exec_prop</a> [lemma, in <a href="backend.PPCgenproof.html">backend.PPCgenproof</a>]<br/>
-<a href="backend.PPCgenproof1.html#exec_straight_one">exec_straight_one</a> [lemma, in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.PPCgenproof1.html#exec_straight_refl">exec_straight_refl</a> [constructor, in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.PPCgenproof1.html#exec_straight_step">exec_straight_step</a> [constructor, in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.PPCgenproof.html#exec_straight_steps">exec_straight_steps</a> [lemma, in <a href="backend.PPCgenproof.html">backend.PPCgenproof</a>]<br/>
-<a href="backend.PPCgenproof.html#exec_straight_steps_1">exec_straight_steps_1</a> [lemma, in <a href="backend.PPCgenproof.html">backend.PPCgenproof</a>]<br/>
-<a href="backend.PPCgenproof.html#exec_straight_steps_2">exec_straight_steps_2</a> [lemma, in <a href="backend.PPCgenproof.html">backend.PPCgenproof</a>]<br/>
-<a href="backend.PPCgenproof1.html#exec_straight_three">exec_straight_three</a> [lemma, in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.PPCgenproof1.html#exec_straight_trans">exec_straight_trans</a> [lemma, in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.PPCgenproof1.html#exec_straight_two">exec_straight_two</a> [lemma, in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.PPC.html#exec_trans">exec_trans</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPCgenproof.html#exec_trans_prop">exec_trans_prop</a> [lemma, in <a href="backend.PPCgenproof.html">backend.PPCgenproof</a>]<br/>
-<a href="backend.Csharpminor.html#expr">expr</a> [inductive, in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Cminor.html#expr">expr</a> [inductive, in <a href="backend.Cminor.html">backend.Cminor</a>]<br/>
-<a href="backend.Csharpminor.html#exprlist">exprlist</a> [inductive, in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Cminor.html#exprlist">exprlist</a> [inductive, in <a href="backend.Cminor.html">backend.Cminor</a>]<br/>
-<a href="backend.RTLgenproof1.html#expr_condexpr_exprlist_ind">expr_condexpr_exprlist_ind</a> [lemma, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="lib.Maps.html#exten">exten</a> [lemma, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="backend.Mem.html#extends">extends</a> [definition, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#extends_refl">extends_refl</a> [lemma, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#extend_inject">extend_inject</a> [definition, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#extend_inject_incr">extend_inject_incr</a> [lemma, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="lib.Coqlib.html#extensionality">extensionality</a> [axiom, in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<br/><br/><a name="global_F"></a><h2>F </h2>
-<a href="backend.Globalenvs.html#find_funct">find_funct</a> [definition, in <a href="backend.Globalenvs.html">backend.Globalenvs</a>]<br/>
-<a href="backend.LTL.html#find_function">find_function</a> [definition, in <a href="backend.LTL.html">backend.LTL</a>]<br/>
-<a href="backend.Mach.html#find_function">find_function</a> [definition, in <a href="backend.Mach.html">backend.Mach</a>]<br/>
-<a href="backend.RTL.html#find_function">find_function</a> [definition, in <a href="backend.RTL.html">backend.RTL</a>]<br/>
-<a href="backend.Linear.html#find_function">find_function</a> [definition, in <a href="backend.Linear.html">backend.Linear</a>]<br/>
-<a href="backend.Allocproof.html#find_function2">find_function2</a> [definition, in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.Globalenvs.html#find_funct_find_funct_ptr">find_funct_find_funct_ptr</a> [lemma, in <a href="backend.Globalenvs.html">backend.Globalenvs</a>]<br/>
-<a href="backend.Globalenvs.html#find_funct_inv">find_funct_inv</a> [lemma, in <a href="backend.Globalenvs.html">backend.Globalenvs</a>]<br/>
-<a href="backend.Globalenvs.html#find_funct_prop">find_funct_prop</a> [lemma, in <a href="backend.Globalenvs.html">backend.Globalenvs</a>]<br/>
-<a href="backend.Globalenvs.html#find_funct_ptr">find_funct_ptr</a> [definition, in <a href="backend.Globalenvs.html">backend.Globalenvs</a>]<br/>
-<a href="backend.Globalenvs.html#find_funct_ptr_inv">find_funct_ptr_inv</a> [lemma, in <a href="backend.Globalenvs.html">backend.Globalenvs</a>]<br/>
-<a href="backend.Globalenvs.html#find_funct_ptr_prop">find_funct_ptr_prop</a> [lemma, in <a href="backend.Globalenvs.html">backend.Globalenvs</a>]<br/>
-<a href="backend.Globalenvs.html#find_funct_ptr_transf">find_funct_ptr_transf</a> [lemma, in <a href="backend.Globalenvs.html">backend.Globalenvs</a>]<br/>
-<a href="backend.Globalenvs.html#find_funct_ptr_transf_partial">find_funct_ptr_transf_partial</a> [lemma, in <a href="backend.Globalenvs.html">backend.Globalenvs</a>]<br/>
-<a href="backend.Globalenvs.html#find_funct_transf">find_funct_transf</a> [lemma, in <a href="backend.Globalenvs.html">backend.Globalenvs</a>]<br/>
-<a href="backend.Globalenvs.html#find_funct_transf_partial">find_funct_transf_partial</a> [lemma, in <a href="backend.Globalenvs.html">backend.Globalenvs</a>]<br/>
-<a href="backend.PPC.html#find_instr">find_instr</a> [definition, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPCgenproof.html#find_instr_in">find_instr_in</a> [lemma, in <a href="backend.PPCgenproof.html">backend.PPCgenproof</a>]<br/>
-<a href="backend.PPCgenproof.html#find_instr_tail">find_instr_tail</a> [lemma, in <a href="backend.PPCgenproof.html">backend.PPCgenproof</a>]<br/>
-<a href="backend.Mach.html#find_label">find_label</a> [definition, in <a href="backend.Mach.html">backend.Mach</a>]<br/>
-<a href="backend.PPCgenproof.html#find_label">find_label</a> [definition, in <a href="backend.PPCgenproof.html">backend.PPCgenproof</a>]<br/>
-<a href="backend.Linear.html#find_label">find_label</a> [definition, in <a href="backend.Linear.html">backend.Linear</a>]<br/>
-<a href="backend.Linearizeproof.html#find_label_cleanup_code">find_label_cleanup_code</a> [lemma, in <a href="backend.Linearizeproof.html">backend.Linearizeproof</a>]<br/>
-<a href="backend.PPCgenproof.html#find_label_goto_label">find_label_goto_label</a> [lemma, in <a href="backend.PPCgenproof.html">backend.PPCgenproof</a>]<br/>
-<a href="backend.Stackingproof.html#find_label_incl">find_label_incl</a> [lemma, in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="backend.Linearizeproof.html#find_label_lin">find_label_lin</a> [lemma, in <a href="backend.Linearizeproof.html">backend.Linearizeproof</a>]<br/>
-<a href="backend.Linearizeproof.html#find_label_lin_block">find_label_lin_block</a> [lemma, in <a href="backend.Linearizeproof.html">backend.Linearizeproof</a>]<br/>
-<a href="backend.Linearizeproof.html#find_label_lin_rec">find_label_lin_rec</a> [lemma, in <a href="backend.Linearizeproof.html">backend.Linearizeproof</a>]<br/>
-<a href="backend.Stackingproof.html#find_label_transl_code">find_label_transl_code</a> [lemma, in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="backend.Linearizeproof.html#find_label_unique">find_label_unique</a> [lemma, in <a href="backend.Linearizeproof.html">backend.Linearizeproof</a>]<br/>
-<a href="backend.RTLgen.html#find_letvar">find_letvar</a> [definition, in <a href="backend.RTLgen.html">backend.RTLgen</a>]<br/>
-<a href="backend.RTLgenproof1.html#find_letvar_incr">find_letvar_incr</a> [lemma, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#find_letvar_in_map">find_letvar_in_map</a> [lemma, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#find_letvar_not_mutated">find_letvar_not_mutated</a> [lemma, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#find_letvar_valid">find_letvar_valid</a> [lemma, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.CSE.html#find_load">find_load</a> [definition, in <a href="backend.CSE.html">backend.CSE</a>]<br/>
-<a href="backend.CSEproof.html#find_load_correct">find_load_correct</a> [lemma, in <a href="backend.CSEproof.html">backend.CSEproof</a>]<br/>
-<a href="backend.CSE.html#find_op">find_op</a> [definition, in <a href="backend.CSE.html">backend.CSE</a>]<br/>
-<a href="backend.CSEproof.html#find_op_correct">find_op_correct</a> [lemma, in <a href="backend.CSEproof.html">backend.CSEproof</a>]<br/>
-<a href="backend.CSE.html#find_rhs">find_rhs</a> [definition, in <a href="backend.CSE.html">backend.CSE</a>]<br/>
-<a href="backend.CSEproof.html#find_rhs_correct">find_rhs_correct</a> [lemma, in <a href="backend.CSEproof.html">backend.CSEproof</a>]<br/>
-<a href="backend.Globalenvs.html#find_symbol">find_symbol</a> [definition, in <a href="backend.Globalenvs.html">backend.Globalenvs</a>]<br/>
-<a href="backend.Globalenvs.html#find_symbol_inv">find_symbol_inv</a> [lemma, in <a href="backend.Globalenvs.html">backend.Globalenvs</a>]<br/>
-<a href="backend.Op.html#find_symbol_offset">find_symbol_offset</a> [definition, in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Globalenvs.html#find_symbol_transf">find_symbol_transf</a> [lemma, in <a href="backend.Globalenvs.html">backend.Globalenvs</a>]<br/>
-<a href="backend.Globalenvs.html#find_symbol_transf_partial">find_symbol_transf_partial</a> [lemma, in <a href="backend.Globalenvs.html">backend.Globalenvs</a>]<br/>
-<a href="backend.CSE.html#find_valnum_rhs">find_valnum_rhs</a> [definition, in <a href="backend.CSE.html">backend.CSE</a>]<br/>
-<a href="backend.CSEproof.html#find_valnum_rhs_correct">find_valnum_rhs_correct</a> [lemma, in <a href="backend.CSEproof.html">backend.CSEproof</a>]<br/>
-<a href="backend.RTLgen.html#find_var">find_var</a> [definition, in <a href="backend.RTLgen.html">backend.RTLgen</a>]<br/>
-<a href="backend.RTLgenproof1.html#find_var_incr">find_var_incr</a> [lemma, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#find_var_in_map">find_var_in_map</a> [lemma, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#find_var_not_mutated">find_var_not_mutated</a> [lemma, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#find_var_valid">find_var_valid</a> [lemma, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.Kildall.html#fixpoint">fixpoint</a> [definition, in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Kildall.html#fixpoint">fixpoint</a> [definition, in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Kildall.html#fixpoint">fixpoint</a> [definition, in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Kildall.html#fixpoint_entry">fixpoint_entry</a> [lemma, in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Kildall.html#fixpoint_entry">fixpoint_entry</a> [lemma, in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Kildall.html#fixpoint_entry">fixpoint_entry</a> [lemma, in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Kildall.html#fixpoint_incr">fixpoint_incr</a> [lemma, in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Kildall.html#fixpoint_invariant">fixpoint_invariant</a> [lemma, in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Kildall.html#fixpoint_solution">fixpoint_solution</a> [lemma, in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Kildall.html#fixpoint_solution">fixpoint_solution</a> [lemma, in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Kildall.html#fixpoint_solution">fixpoint_solution</a> [lemma, in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Stacking.html#FI_arg">FI_arg</a> [constructor, in <a href="backend.Stacking.html">backend.Stacking</a>]<br/>
-<a href="backend.Stacking.html#FI_local">FI_local</a> [constructor, in <a href="backend.Stacking.html">backend.Stacking</a>]<br/>
-<a href="backend.Stacking.html#FI_saved_float">FI_saved_float</a> [constructor, in <a href="backend.Stacking.html">backend.Stacking</a>]<br/>
-<a href="backend.Stacking.html#FI_saved_int">FI_saved_int</a> [constructor, in <a href="backend.Stacking.html">backend.Stacking</a>]<br/>
-<a href="lib.Inclusion.html#flatten">flatten</a> [definition, in <a href="lib.Inclusion.html">lib.Inclusion</a>]<br/>
-<a href="lib.Inclusion.html#flatten_aux">flatten_aux</a> [definition, in <a href="lib.Inclusion.html">lib.Inclusion</a>]<br/>
-<a href="lib.Inclusion.html#flatten_aux_valid_A">flatten_aux_valid_A</a> [lemma, in <a href="lib.Inclusion.html">lib.Inclusion</a>]<br/>
-<a href="lib.Inclusion.html#flatten_valid_A">flatten_valid_A</a> [lemma, in <a href="lib.Inclusion.html">lib.Inclusion</a>]<br/>
-<a href="lib.Floats.html#float">float</a> [axiom, in <a href="lib.Floats.html">lib.Floats</a>]<br/>
-<a href="lib.Floats.html#Float">Float</a> [module, in <a href="lib.Floats.html">lib.Floats</a>]<br/>
-<a href="backend.PPCgen.html#floatcomp">floatcomp</a> [definition, in <a href="backend.PPCgen.html">backend.PPCgen</a>]<br/>
-<a href="backend.PPCgenproof1.html#floatcomp_correct">floatcomp_correct</a> [lemma, in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.Values.html#floatofint">floatofint</a> [definition, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="lib.Floats.html#floatofint">floatofint</a> [axiom, in <a href="lib.Floats.html">lib.Floats</a>]<br/>
-<a href="backend.Cmconstr.html#floatofint">floatofint</a> [definition, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#floatofintu">floatofintu</a> [definition, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Values.html#floatofintu">floatofintu</a> [definition, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="lib.Floats.html#floatofintu">floatofintu</a> [axiom, in <a href="lib.Floats.html">lib.Floats</a>]<br/>
-<a href="lib.Floats.html">Floats</a> [library]<br/>
-<a href="backend.Lineartyping.html#float_callee_save">float_callee_save</a> [definition, in <a href="backend.Lineartyping.html">backend.Lineartyping</a>]<br/>
-<a href="backend.Linearizetyping.html#float_callee_save_bound">float_callee_save_bound</a> [lemma, in <a href="backend.Linearizetyping.html">backend.Linearizetyping</a>]<br/>
-<a href="backend.Conventions.html#float_callee_save_norepet">float_callee_save_norepet</a> [lemma, in <a href="backend.Conventions.html">backend.Conventions</a>]<br/>
-<a href="backend.Conventions.html#float_callee_save_not_destroyed">float_callee_save_not_destroyed</a> [lemma, in <a href="backend.Conventions.html">backend.Conventions</a>]<br/>
-<a href="backend.Conventions.html#float_callee_save_regs">float_callee_save_regs</a> [definition, in <a href="backend.Conventions.html">backend.Conventions</a>]<br/>
-<a href="backend.Conventions.html#float_callee_save_type">float_callee_save_type</a> [lemma, in <a href="backend.Conventions.html">backend.Conventions</a>]<br/>
-<a href="backend.Lineartyping.html#float_local">float_local</a> [definition, in <a href="backend.Lineartyping.html">backend.Lineartyping</a>]<br/>
-<a href="backend.Linearizetyping.html#float_local_slot_bound">float_local_slot_bound</a> [lemma, in <a href="backend.Linearizetyping.html">backend.Linearizetyping</a>]<br/>
-<a href="backend.Conventions.html#float_param_regs">float_param_regs</a> [definition, in <a href="backend.Conventions.html">backend.Conventions</a>]<br/>
-<a href="backend.Csharpminor.html#fn_params_names">fn_params_names</a> [definition, in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Csharpminor.html#fn_variables">fn_variables</a> [definition, in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Csharpminor.html#fn_vars_names">fn_vars_names</a> [definition, in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="lib.Sets.html#fold">fold</a> [definition, in <a href="lib.Sets.html">lib.Sets</a>]<br/>
-<a href="lib.Maps.html#fold">fold</a> [definition, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="backend.RTLtyping.html#fold2">fold2</a> [definition, in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="lib.Maps.html#fold_spec">fold_spec</a> [lemma, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Sets.html#fold_spec">fold_spec</a> [lemma, in <a href="lib.Sets.html">lib.Sets</a>]<br/>
-<a href="lib.Sets.html#for_all">for_all</a> [definition, in <a href="lib.Sets.html">lib.Sets</a>]<br/>
-<a href="lib.Sets.html#for_all_spec">for_all_spec</a> [lemma, in <a href="lib.Sets.html">lib.Sets</a>]<br/>
-<a href="backend.Parallelmove.html#Fpmov_correct">Fpmov_correct</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#Fpmov_correctMoves">Fpmov_correctMoves</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#Fpmov_correct1">Fpmov_correct1</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#Fpmov_correct2">Fpmov_correct2</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#Fpmov_correct_ext">Fpmov_correct_ext</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#Fpmov_correct_IT3">Fpmov_correct_IT3</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#Fpmov_correct_map">Fpmov_correct_map</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.PPC.html#FPR0">FPR0</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#FPR1">FPR1</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#FPR10">FPR10</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#FPR11">FPR11</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#FPR12">FPR12</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#FPR13">FPR13</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#FPR14">FPR14</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#FPR15">FPR15</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#FPR16">FPR16</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#FPR17">FPR17</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#FPR18">FPR18</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#FPR19">FPR19</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#FPR2">FPR2</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#FPR20">FPR20</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#FPR21">FPR21</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#FPR22">FPR22</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#FPR23">FPR23</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#FPR24">FPR24</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#FPR25">FPR25</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#FPR26">FPR26</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#FPR27">FPR27</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#FPR28">FPR28</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#FPR29">FPR29</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#FPR3">FPR3</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#FPR30">FPR30</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#FPR31">FPR31</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#FPR4">FPR4</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#FPR5">FPR5</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#FPR6">FPR6</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#FPR7">FPR7</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#FPR8">FPR8</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#FPR9">FPR9</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#FR">FR</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.Cminorgenproof.html#frame">frame</a> [inductive, in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Machabstr.html#frame">frame</a> [definition, in <a href="backend.Machabstr.html">backend.Machabstr</a>]<br/>
-<a href="backend.Stacking.html#frame_env">frame_env</a> [inductive, in <a href="backend.Stacking.html">backend.Stacking</a>]<br/>
-<a href="backend.Stacking.html#frame_index">frame_index</a> [inductive, in <a href="backend.Stacking.html">backend.Stacking</a>]<br/>
-<a href="backend.Machabstr2mach.html#frame_match">frame_match</a> [inductive, in <a href="backend.Machabstr2mach.html">backend.Machabstr2mach</a>]<br/>
-<a href="backend.Machabstr2mach.html#frame_match_alloc">frame_match_alloc</a> [lemma, in <a href="backend.Machabstr2mach.html">backend.Machabstr2mach</a>]<br/>
-<a href="backend.Machabstr2mach.html#frame_match_exten">frame_match_exten</a> [lemma, in <a href="backend.Machabstr2mach.html">backend.Machabstr2mach</a>]<br/>
-<a href="backend.Machabstr2mach.html#frame_match_free">frame_match_free</a> [lemma, in <a href="backend.Machabstr2mach.html">backend.Machabstr2mach</a>]<br/>
-<a href="backend.Machabstr2mach.html#frame_match_get_slot">frame_match_get_slot</a> [lemma, in <a href="backend.Machabstr2mach.html">backend.Machabstr2mach</a>]<br/>
-<a href="backend.Machabstr2mach.html#frame_match_intro">frame_match_intro</a> [constructor, in <a href="backend.Machabstr2mach.html">backend.Machabstr2mach</a>]<br/>
-<a href="backend.Machabstr2mach.html#frame_match_load">frame_match_load</a> [lemma, in <a href="backend.Machabstr2mach.html">backend.Machabstr2mach</a>]<br/>
-<a href="backend.Machabstr2mach.html#frame_match_new">frame_match_new</a> [lemma, in <a href="backend.Machabstr2mach.html">backend.Machabstr2mach</a>]<br/>
-<a href="backend.Machabstr2mach.html#frame_match_set_slot">frame_match_set_slot</a> [lemma, in <a href="backend.Machabstr2mach.html">backend.Machabstr2mach</a>]<br/>
-<a href="backend.Machabstr2mach.html#frame_match_store">frame_match_store</a> [lemma, in <a href="backend.Machabstr2mach.html">backend.Machabstr2mach</a>]<br/>
-<a href="backend.Machabstr2mach.html#frame_match_store_ok">frame_match_store_ok</a> [lemma, in <a href="backend.Machabstr2mach.html">backend.Machabstr2mach</a>]<br/>
-<a href="backend.Machabstr2mach.html#frame_match_store_stack_other">frame_match_store_stack_other</a> [lemma, in <a href="backend.Machabstr2mach.html">backend.Machabstr2mach</a>]<br/>
-<a href="backend.Mem.html#free">free</a> [definition, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#free_empty_bounds">free_empty_bounds</a> [lemma, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#free_extends">free_extends</a> [lemma, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#free_first_inject">free_first_inject</a> [lemma, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#free_first_list_inject">free_first_list_inject</a> [lemma, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#free_inject">free_inject</a> [lemma, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#free_list">free_list</a> [definition, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#free_snd_inject">free_snd_inject</a> [lemma, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.PPC.html#freg">freg</a> [inductive, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#freg_eq">freg_eq</a> [lemma, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPCgen.html#freg_of">freg_of</a> [definition, in <a href="backend.PPCgen.html">backend.PPCgen</a>]<br/>
-<a href="backend.PPCgenproof1.html#freg_of_is_data_reg">freg_of_is_data_reg</a> [lemma, in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.PPCgenproof1.html#freg_of_not_FPR13">freg_of_not_FPR13</a> [lemma, in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.PPCgenproof1.html#freg_val">freg_val</a> [lemma, in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.Mem.html#fresh_block_alloc">fresh_block_alloc</a> [lemma, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Locations.html#FT1">FT1</a> [constructor, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#FT2">FT2</a> [constructor, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#FT3">FT3</a> [constructor, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Mach.html#function">function</a> [inductive, in <a href="backend.Mach.html">backend.Mach</a>]<br/>
-<a href="backend.Csharpminor.html#function">function</a> [inductive, in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.RTL.html#function">function</a> [inductive, in <a href="backend.RTL.html">backend.RTL</a>]<br/>
-<a href="backend.LTL.html#function">function</a> [inductive, in <a href="backend.LTL.html">backend.LTL</a>]<br/>
-<a href="backend.Cminor.html#function">function</a> [inductive, in <a href="backend.Cminor.html">backend.Cminor</a>]<br/>
-<a href="backend.Linear.html#function">function</a> [inductive, in <a href="backend.Linear.html">backend.Linear</a>]<br/>
-<a href="backend.Globalenvs.html#functions_globalenv">functions_globalenv</a> [lemma, in <a href="backend.Globalenvs.html">backend.Globalenvs</a>]<br/>
-<a href="backend.Constpropproof.html#functions_translated">functions_translated</a> [lemma, in <a href="backend.Constpropproof.html">backend.Constpropproof</a>]<br/>
-<a href="backend.Tunnelingproof.html#functions_translated">functions_translated</a> [lemma, in <a href="backend.Tunnelingproof.html">backend.Tunnelingproof</a>]<br/>
-<a href="backend.PPCgenproof.html#functions_translated">functions_translated</a> [lemma, in <a href="backend.PPCgenproof.html">backend.PPCgenproof</a>]<br/>
-<a href="backend.Allocproof.html#functions_translated">functions_translated</a> [lemma, in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.Linearizeproof.html#functions_translated">functions_translated</a> [lemma, in <a href="backend.Linearizeproof.html">backend.Linearizeproof</a>]<br/>
-<a href="backend.Stackingproof.html#functions_translated">functions_translated</a> [lemma, in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="backend.CSEproof.html#functions_translated">functions_translated</a> [lemma, in <a href="backend.CSEproof.html">backend.CSEproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#functions_translated">functions_translated</a> [lemma, in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.RTLgenproof.html#functions_translated">functions_translated</a> [lemma, in <a href="backend.RTLgenproof.html">backend.RTLgenproof</a>]<br/>
-<a href="backend.PPCgenproof.html#functions_translated_no_overflow">functions_translated_no_overflow</a> [lemma, in <a href="backend.PPCgenproof.html">backend.PPCgenproof</a>]<br/>
-<a href="backend.PPCgenproof.html#functions_translated_2">functions_translated_2</a> [lemma, in <a href="backend.PPCgenproof.html">backend.PPCgenproof</a>]<br/>
-<a href="backend.Lineartyping.html#function_bounds">function_bounds</a> [definition, in <a href="backend.Lineartyping.html">backend.Lineartyping</a>]<br/>
-<a href="backend.Cminorgenproof.html#function_entry_ok">function_entry_ok</a> [lemma, in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Linearizeproof.html#function_ptr_translated">function_ptr_translated</a> [lemma, in <a href="backend.Linearizeproof.html">backend.Linearizeproof</a>]<br/>
-<a href="backend.Allocproof.html#function_ptr_translated">function_ptr_translated</a> [lemma, in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.Stackingproof.html#function_ptr_translated">function_ptr_translated</a> [lemma, in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#function_ptr_translated">function_ptr_translated</a> [lemma, in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.RTLgenproof.html#function_ptr_translated">function_ptr_translated</a> [lemma, in <a href="backend.RTLgenproof.html">backend.RTLgenproof</a>]<br/>
-<a href="backend.Constpropproof.html#function_ptr_translated">function_ptr_translated</a> [lemma, in <a href="backend.Constpropproof.html">backend.Constpropproof</a>]<br/>
-<a href="backend.Tunnelingproof.html#function_ptr_translated">function_ptr_translated</a> [lemma, in <a href="backend.Tunnelingproof.html">backend.Tunnelingproof</a>]<br/>
-<a href="backend.CSEproof.html#funct_ptr_translated">funct_ptr_translated</a> [lemma, in <a href="backend.CSEproof.html">backend.CSEproof</a>]<br/>
-<a href="backend.Locations.html#F1">F1</a> [constructor, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#F10">F10</a> [constructor, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#F14">F14</a> [constructor, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#F15">F15</a> [constructor, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#F16">F16</a> [constructor, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#F17">F17</a> [constructor, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#F18">F18</a> [constructor, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#F19">F19</a> [constructor, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#F2">F2</a> [constructor, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Parallelmove.html#f2ind">f2ind</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#f2ind'">f2ind'</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Locations.html#F20">F20</a> [constructor, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#F21">F21</a> [constructor, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#F22">F22</a> [constructor, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#F23">F23</a> [constructor, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#F24">F24</a> [constructor, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#F25">F25</a> [constructor, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#F26">F26</a> [constructor, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#F27">F27</a> [constructor, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#F28">F28</a> [constructor, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#F29">F29</a> [constructor, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#F3">F3</a> [constructor, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#F30">F30</a> [constructor, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#F31">F31</a> [constructor, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#F4">F4</a> [constructor, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#F5">F5</a> [constructor, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#F6">F6</a> [constructor, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#F7">F7</a> [constructor, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#F8">F8</a> [constructor, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#F9">F9</a> [constructor, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<br/><br/><a name="global_G"></a><h2>G </h2>
-<a href="lib.Maps.html#gcombine">gcombine</a> [lemma, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Lattice.html#ge">ge</a> [definition, in <a href="lib.Lattice.html">lib.Lattice</a>]<br/>
-<a href="backend.CSE.html#ge">ge</a> [definition, in <a href="backend.CSE.html">backend.CSE</a>]<br/>
-<a href="lib.Lattice.html#ge">ge</a> [definition, in <a href="lib.Lattice.html">lib.Lattice</a>]<br/>
-<a href="backend.Constprop.html#ge">ge</a> [definition, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="lib.Lattice.html#ge">ge</a> [definition, in <a href="lib.Lattice.html">lib.Lattice</a>]<br/>
-<a href="lib.Sets.html#ge">ge</a> [definition, in <a href="lib.Sets.html">lib.Sets</a>]<br/>
-<a href="lib.Maps.html#gempty">gempty</a> [lemma, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="backend.Cminor.html#genv">genv</a> [definition, in <a href="backend.Cminor.html">backend.Cminor</a>]<br/>
-<a href="backend.LTL.html#genv">genv</a> [definition, in <a href="backend.LTL.html">backend.LTL</a>]<br/>
-<a href="backend.Globalenvs.html#Genv">Genv</a> [module, in <a href="backend.Globalenvs.html">backend.Globalenvs</a>]<br/>
-<a href="backend.PPC.html#genv">genv</a> [definition, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.Globalenvs.html#GENV">GENV</a> [module, in <a href="backend.Globalenvs.html">backend.Globalenvs</a>]<br/>
-<a href="backend.Csharpminor.html#genv">genv</a> [definition, in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Globalenvs.html#genv">genv</a> [inductive, in <a href="backend.Globalenvs.html">backend.Globalenvs</a>]<br/>
-<a href="backend.RTL.html#genv">genv</a> [definition, in <a href="backend.RTL.html">backend.RTL</a>]<br/>
-<a href="backend.Mach.html#genv">genv</a> [definition, in <a href="backend.Mach.html">backend.Mach</a>]<br/>
-<a href="backend.Linear.html#genv">genv</a> [definition, in <a href="backend.Linear.html">backend.Linear</a>]<br/>
-<a href="lib.Maps.html#get">get</a> [definition, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#get">get</a> [definition, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#get">get</a> [definition, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="backend.Parallelmove.html#Get">Get</a> [definition, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Locations.html#get">get</a> [definition, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="lib.Lattice.html#get">get</a> [definition, in <a href="lib.Lattice.html">lib.Lattice</a>]<br/>
-<a href="lib.Maps.html#get">get</a> [definition, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="backend.Parallelmove.html#get">get</a> [definition, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.RTLtyping.html#get">get</a> [definition, in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.Parallelmove.html#getdst">getdst</a> [definition, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#getdst_add">getdst_add</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#getdst_app">getdst_app</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Alloctyping_aux.html#getdst_f">getdst_f</a> [lemma, in <a href="backend.Alloctyping_aux.html">backend.Alloctyping_aux</a>]<br/>
-<a href="backend.Allocproof_aux.html#getdst_lists2moves">getdst_lists2moves</a> [lemma, in <a href="backend.Allocproof_aux.html">backend.Allocproof_aux</a>]<br/>
-<a href="backend.Parallelmove.html#getdst_map">getdst_map</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Mem.html#getN">getN</a> [definition, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#getN_agree">getN_agree</a> [lemma, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#getN_init">getN_init</a> [lemma, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#getN_inject">getN_inject</a> [lemma, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#getN_setN_mismatch">getN_setN_mismatch</a> [lemma, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#getN_setN_other">getN_setN_other</a> [lemma, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#getN_setN_overlap">getN_setN_overlap</a> [lemma, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#getN_setN_same">getN_setN_same</a> [lemma, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Parallelmove.html#getsrc">getsrc</a> [definition, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Allocproof_aux.html#getsrcdst_app">getsrcdst_app</a> [lemma, in <a href="backend.Allocproof_aux.html">backend.Allocproof_aux</a>]<br/>
-<a href="backend.Parallelmove.html#getsrc_add">getsrc_add</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#getsrc_add1">getsrc_add1</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#getsrc_app">getsrc_app</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Alloctyping_aux.html#getsrc_f">getsrc_f</a> [lemma, in <a href="backend.Alloctyping_aux.html">backend.Alloctyping_aux</a>]<br/>
-<a href="backend.Parallelmove.html#getsrc_map">getsrc_map</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.RTLtyping.html#get_add_1">get_add_1</a> [lemma, in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.RTLtyping.html#get_add_2">get_add_2</a> [lemma, in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="lib.Lattice.html#get_bot">get_bot</a> [lemma, in <a href="lib.Lattice.html">lib.Lattice</a>]<br/>
-<a href="backend.RTLtyping.html#get_empty">get_empty</a> [lemma, in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.Parallelmove.html#get_noWrite">get_noWrite</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#get_pexec_id_noWrite">get_pexec_id_noWrite</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Machabstr.html#get_slot">get_slot</a> [inductive, in <a href="backend.Machabstr.html">backend.Machabstr</a>]<br/>
-<a href="backend.Stackingproof.html#get_slot_index">get_slot_index</a> [lemma, in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="backend.Machabstr.html#get_slot_intro">get_slot_intro</a> [constructor, in <a href="backend.Machabstr.html">backend.Machabstr</a>]<br/>
-<a href="backend.Stackingproof.html#get_slot_ok">get_slot_ok</a> [lemma, in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="lib.Lattice.html#get_top">get_top</a> [lemma, in <a href="lib.Lattice.html">lib.Lattice</a>]<br/>
-<a href="backend.Parallelmove.html#get_update">get_update</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#get_update_diff">get_update_diff</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#get_update_id">get_update_id</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#get_update_ndiff">get_update_ndiff</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="lib.Maps.html#get_xget_h">get_xget_h</a> [lemma, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Lattice.html#ge_bot">ge_bot</a> [lemma, in <a href="lib.Lattice.html">lib.Lattice</a>]<br/>
-<a href="lib.Lattice.html#ge_bot">ge_bot</a> [lemma, in <a href="lib.Lattice.html">lib.Lattice</a>]<br/>
-<a href="lib.Sets.html#ge_bot">ge_bot</a> [lemma, in <a href="lib.Sets.html">lib.Sets</a>]<br/>
-<a href="lib.Lattice.html#ge_bot">ge_bot</a> [lemma, in <a href="lib.Lattice.html">lib.Lattice</a>]<br/>
-<a href="backend.Constprop.html#ge_bot">ge_bot</a> [lemma, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="lib.Lattice.html#ge_lub_left">ge_lub_left</a> [lemma, in <a href="lib.Lattice.html">lib.Lattice</a>]<br/>
-<a href="lib.Sets.html#ge_lub_left">ge_lub_left</a> [lemma, in <a href="lib.Sets.html">lib.Sets</a>]<br/>
-<a href="backend.Constprop.html#ge_lub_left">ge_lub_left</a> [lemma, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="lib.Lattice.html#ge_lub_left">ge_lub_left</a> [lemma, in <a href="lib.Lattice.html">lib.Lattice</a>]<br/>
-<a href="lib.Lattice.html#ge_lub_left">ge_lub_left</a> [lemma, in <a href="lib.Lattice.html">lib.Lattice</a>]<br/>
-<a href="lib.Sets.html#ge_lub_right">ge_lub_right</a> [lemma, in <a href="lib.Sets.html">lib.Sets</a>]<br/>
-<a href="lib.Lattice.html#ge_refl">ge_refl</a> [lemma, in <a href="lib.Lattice.html">lib.Lattice</a>]<br/>
-<a href="lib.Sets.html#ge_refl">ge_refl</a> [lemma, in <a href="lib.Sets.html">lib.Sets</a>]<br/>
-<a href="lib.Lattice.html#ge_refl">ge_refl</a> [lemma, in <a href="lib.Lattice.html">lib.Lattice</a>]<br/>
-<a href="lib.Lattice.html#ge_refl">ge_refl</a> [lemma, in <a href="lib.Lattice.html">lib.Lattice</a>]<br/>
-<a href="backend.Constprop.html#ge_refl">ge_refl</a> [lemma, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="lib.Lattice.html#ge_top">ge_top</a> [lemma, in <a href="lib.Lattice.html">lib.Lattice</a>]<br/>
-<a href="backend.Constprop.html#ge_top">ge_top</a> [lemma, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="lib.Lattice.html#ge_top">ge_top</a> [lemma, in <a href="lib.Lattice.html">lib.Lattice</a>]<br/>
-<a href="lib.Lattice.html#ge_top">ge_top</a> [lemma, in <a href="lib.Lattice.html">lib.Lattice</a>]<br/>
-<a href="lib.Lattice.html#ge_trans">ge_trans</a> [lemma, in <a href="lib.Lattice.html">lib.Lattice</a>]<br/>
-<a href="backend.Constprop.html#ge_trans">ge_trans</a> [lemma, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="lib.Sets.html#ge_trans">ge_trans</a> [lemma, in <a href="lib.Sets.html">lib.Sets</a>]<br/>
-<a href="lib.Lattice.html#ge_trans">ge_trans</a> [lemma, in <a href="lib.Lattice.html">lib.Lattice</a>]<br/>
-<a href="lib.Lattice.html#ge_trans">ge_trans</a> [lemma, in <a href="lib.Lattice.html">lib.Lattice</a>]<br/>
-<a href="lib.Maps.html#gi">gi</a> [lemma, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#gi">gi</a> [lemma, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#gi">gi</a> [lemma, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#gleaf">gleaf</a> [lemma, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="backend.Globalenvs.html#globalenv">globalenv</a> [definition, in <a href="backend.Globalenvs.html">backend.Globalenvs</a>]<br/>
-<a href="backend.Globalenvs.html">Globalenvs</a> [library]<br/>
-<a href="backend.Globalenvs.html#globalenv_initmem">globalenv_initmem</a> [definition, in <a href="backend.Globalenvs.html">backend.Globalenvs</a>]<br/>
-<a href="lib.Maps.html#gmap">gmap</a> [lemma, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#gmap">gmap</a> [lemma, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#gmap">gmap</a> [lemma, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#gmap">gmap</a> [lemma, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="backend.Kildall.html#good_state">good_state</a> [definition, in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.PPC.html#goto_label">goto_label</a> [definition, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#GPR0">GPR0</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#GPR1">GPR1</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#GPR10">GPR10</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#GPR11">GPR11</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#GPR12">GPR12</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#GPR13">GPR13</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#GPR14">GPR14</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#GPR15">GPR15</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#GPR16">GPR16</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#GPR17">GPR17</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#GPR18">GPR18</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#GPR19">GPR19</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#GPR2">GPR2</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#GPR20">GPR20</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#GPR21">GPR21</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#GPR22">GPR22</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#GPR23">GPR23</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#GPR24">GPR24</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#GPR25">GPR25</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#GPR26">GPR26</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#GPR27">GPR27</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#GPR28">GPR28</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#GPR29">GPR29</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#GPR3">GPR3</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#GPR30">GPR30</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#GPR31">GPR31</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#GPR4">GPR4</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#GPR5">GPR5</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#GPR6">GPR6</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#GPR7">GPR7</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#GPR8">GPR8</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#GPR9">GPR9</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#gpr_or_zero">gpr_or_zero</a> [definition, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPCgenproof1.html#gpr_or_zero_not_zero">gpr_or_zero_not_zero</a> [lemma, in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.PPCgenproof1.html#gpr_or_zero_zero">gpr_or_zero_zero</a> [lemma, in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.InterfGraph.html#graph">graph</a> [inductive, in <a href="backend.InterfGraph.html">backend.InterfGraph</a>]<br/>
-<a href="backend.Coloring.html#graph_coloring">graph_coloring</a> [axiom, in <a href="backend.Coloring.html">backend.Coloring</a>]<br/>
-<a href="backend.InterfGraph.html#graph_incl">graph_incl</a> [definition, in <a href="backend.InterfGraph.html">backend.InterfGraph</a>]<br/>
-<a href="backend.Coloringproof.html#graph_incl_refl">graph_incl_refl</a> [lemma, in <a href="backend.Coloringproof.html">backend.Coloringproof</a>]<br/>
-<a href="backend.InterfGraph.html#graph_incl_trans">graph_incl_trans</a> [lemma, in <a href="backend.InterfGraph.html">backend.InterfGraph</a>]<br/>
-<a href="lib.Maps.html#gro">gro</a> [lemma, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#grs">grs</a> [lemma, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#gsident">gsident</a> [lemma, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#gsident">gsident</a> [lemma, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#gsident">gsident</a> [lemma, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#gso">gso</a> [lemma, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="backend.Locations.html#gso">gso</a> [lemma, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="lib.Maps.html#gso">gso</a> [lemma, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#gso">gso</a> [lemma, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Lattice.html#gso">gso</a> [lemma, in <a href="lib.Lattice.html">lib.Lattice</a>]<br/>
-<a href="lib.Maps.html#gso">gso</a> [lemma, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#gss">gss</a> [lemma, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#gss">gss</a> [lemma, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="backend.Locations.html#gss">gss</a> [lemma, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="lib.Maps.html#gss">gss</a> [lemma, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Lattice.html#gss">gss</a> [lemma, in <a href="lib.Lattice.html">lib.Lattice</a>]<br/>
-<a href="lib.Maps.html#gss">gss</a> [lemma, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#gsspec">gsspec</a> [lemma, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#gsspec">gsspec</a> [lemma, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#gsspec">gsspec</a> [lemma, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#gsspec">gsspec</a> [lemma, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<br/><br/><a name="global_H"></a><h2>H </h2>
-<a href="lib.Integers.html#half_modulus">half_modulus</a> [definition, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Values.html#has_type">has_type</a> [definition, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Values.html#has_type_list">has_type_list</a> [definition, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Parallelmove.html#head_but_last">head_but_last</a> [definition, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Mem.html#high_bound">high_bound</a> [definition, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#high_bound_alloc">high_bound_alloc</a> [lemma, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#high_bound_free">high_bound_free</a> [lemma, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#high_bound_store">high_bound_store</a> [lemma, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.PPC.html#high_half_signed">high_half_signed</a> [axiom, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#high_half_signed_type">high_half_signed_type</a> [axiom, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPCgenproof1.html#high_half_signed_zero">high_half_signed_zero</a> [lemma, in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.PPC.html#high_half_unsigned">high_half_unsigned</a> [axiom, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#high_half_unsigned_type">high_half_unsigned_type</a> [axiom, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPCgenproof1.html#high_half_unsigned_zero">high_half_unsigned_zero</a> [lemma, in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.PPCgen.html#high_s">high_s</a> [definition, in <a href="backend.PPCgen.html">backend.PPCgen</a>]<br/>
-<a href="backend.PPCgen.html#high_u">high_u</a> [definition, in <a href="backend.PPCgen.html">backend.PPCgen</a>]<br/>
-<br/><br/><a name="global_I"></a><h2>I </h2>
-<a href="backend.AST.html#ident">ident</a> [definition, in <a href="backend.AST.html">backend.AST</a>]<br/>
-<a href="lib.union_find.html#identify">identify</a> [definition, in <a href="lib.union_find.html">lib.union_find</a>]<br/>
-<a href="lib.union_find.html#identify_aux_decomp">identify_aux_decomp</a> [lemma, in <a href="lib.union_find.html">lib.union_find</a>]<br/>
-<a href="lib.union_find.html#identify_base">identify_base</a> [definition, in <a href="lib.union_find.html">lib.union_find</a>]<br/>
-<a href="lib.union_find.html#identify_base_a_maps_to_b">identify_base_a_maps_to_b</a> [lemma, in <a href="lib.union_find.html">lib.union_find</a>]<br/>
-<a href="lib.union_find.html#identify_base_b_canon">identify_base_b_canon</a> [lemma, in <a href="lib.union_find.html">lib.union_find</a>]<br/>
-<a href="lib.union_find.html#identify_base_order_wf">identify_base_order_wf</a> [lemma, in <a href="lib.union_find.html">lib.union_find</a>]<br/>
-<a href="lib.union_find.html#identify_base_repr">identify_base_repr</a> [lemma, in <a href="lib.union_find.html">lib.union_find</a>]<br/>
-<a href="lib.union_find.html#identify_base_repr_order">identify_base_repr_order</a> [lemma, in <a href="lib.union_find.html">lib.union_find</a>]<br/>
-<a href="lib.union_find.html#identify_base_sameclass_1">identify_base_sameclass_1</a> [lemma, in <a href="lib.union_find.html">lib.union_find</a>]<br/>
-<a href="lib.union_find.html#identify_base_sameclass_2">identify_base_sameclass_2</a> [lemma, in <a href="lib.union_find.html">lib.union_find</a>]<br/>
-<a href="backend.Cminorgen.html#Identset">Identset</a> [module, in <a href="backend.Cminorgen.html">backend.Cminorgen</a>]<br/>
-<a href="backend.AST.html#ident_eq">ident_eq</a> [definition, in <a href="backend.AST.html">backend.AST</a>]<br/>
-<a href="backend.Cmconstr.html#ifthenelse">ifthenelse</a> [definition, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="lib.Maps.html#IMap">IMap</a> [module, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="backend.PPC.html#immediate">immediate</a> [inductive, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#immediate">immediate</a> [inductive, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#immediate">immediate</a> [inductive, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#immediate">immediate</a> [inductive, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#immediate">immediate</a> [inductive, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#immediate">immediate</a> [inductive, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.RTLtyping.html#included">included</a> [definition, in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.RTLtyping.html#included_consistent">included_consistent</a> [lemma, in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.RTLtyping.html#included_identify">included_identify</a> [lemma, in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.RTLtyping.html#included_mapped">included_mapped</a> [lemma, in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.RTLtyping.html#included_mapped_forall">included_mapped_forall</a> [lemma, in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.RTLtyping.html#included_refl">included_refl</a> [lemma, in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.RTLtyping.html#included_trans">included_trans</a> [lemma, in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="lib.Inclusion.html">Inclusion</a> [library]<br/>
-<a href="lib.Inclusion.html#inclusion_theorem">inclusion_theorem</a> [lemma, in <a href="lib.Inclusion.html">lib.Inclusion</a>]<br/>
-<a href="lib.Coqlib.html#incl_app_inv_l">incl_app_inv_l</a> [lemma, in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#incl_app_inv_r">incl_app_inv_r</a> [lemma, in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#incl_cons_inv">incl_cons_inv</a> [lemma, in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="backend.Alloctyping_aux.html#incl_dst">incl_dst</a> [lemma, in <a href="backend.Alloctyping_aux.html">backend.Alloctyping_aux</a>]<br/>
-<a href="backend.Machtyping.html#incl_find_label">incl_find_label</a> [lemma, in <a href="backend.Machtyping.html">backend.Machtyping</a>]<br/>
-<a href="backend.Alloctyping_aux.html#incl_nil">incl_nil</a> [lemma, in <a href="backend.Alloctyping_aux.html">backend.Alloctyping_aux</a>]<br/>
-<a href="lib.Coqlib.html#incl_same_head">incl_same_head</a> [lemma, in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="backend.Alloctyping_aux.html#incl_src">incl_src</a> [lemma, in <a href="backend.Alloctyping_aux.html">backend.Alloctyping_aux</a>]<br/>
-<a href="backend.Locations.html#Incoming">Incoming</a> [constructor, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.LTLtyping.html#Incoming">Incoming</a> [inductive, in <a href="backend.LTLtyping.html">backend.LTLtyping</a>]<br/>
-<a href="backend.Lineartyping.html#Incoming">Incoming</a> [inductive, in <a href="backend.Lineartyping.html">backend.Lineartyping</a>]<br/>
-<a href="backend.Locations.html#index">index</a> [definition, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="lib.Maps.html#index">index</a> [definition, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#index">index</a> [definition, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="backend.Locations.html#IndexedMreg">IndexedMreg</a> [module, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="lib.Maps.html#INDEXED_TYPE">INDEXED_TYPE</a> [module, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="backend.Stackingproof.html#index_arg_valid">index_arg_valid</a> [lemma, in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="backend.Stackingproof.html#index_diff">index_diff</a> [definition, in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="backend.Conventions.html#index_float_callee_save">index_float_callee_save</a> [definition, in <a href="backend.Conventions.html">backend.Conventions</a>]<br/>
-<a href="backend.Conventions.html#index_float_callee_save_inj">index_float_callee_save_inj</a> [lemma, in <a href="backend.Conventions.html">backend.Conventions</a>]<br/>
-<a href="backend.Conventions.html#index_float_callee_save_pos">index_float_callee_save_pos</a> [lemma, in <a href="backend.Conventions.html">backend.Conventions</a>]<br/>
-<a href="backend.Conventions.html#index_float_callee_save_pos2">index_float_callee_save_pos2</a> [lemma, in <a href="backend.Conventions.html">backend.Conventions</a>]<br/>
-<a href="lib.Maps.html#index_inj">index_inj</a> [lemma, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="backend.Locations.html#index_inj">index_inj</a> [lemma, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="lib.Maps.html#index_inj">index_inj</a> [lemma, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="backend.Conventions.html#index_int_callee_save">index_int_callee_save</a> [definition, in <a href="backend.Conventions.html">backend.Conventions</a>]<br/>
-<a href="backend.Conventions.html#index_int_callee_save_inj">index_int_callee_save_inj</a> [lemma, in <a href="backend.Conventions.html">backend.Conventions</a>]<br/>
-<a href="backend.Conventions.html#index_int_callee_save_pos">index_int_callee_save_pos</a> [lemma, in <a href="backend.Conventions.html">backend.Conventions</a>]<br/>
-<a href="backend.Conventions.html#index_int_callee_save_pos2">index_int_callee_save_pos2</a> [lemma, in <a href="backend.Conventions.html">backend.Conventions</a>]<br/>
-<a href="backend.Stackingproof.html#index_local_valid">index_local_valid</a> [lemma, in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="backend.Stackingproof.html#index_saved_float_valid">index_saved_float_valid</a> [lemma, in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="backend.Stackingproof.html#index_saved_int_valid">index_saved_int_valid</a> [lemma, in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="backend.Stackingproof.html#index_val">index_val</a> [definition, in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="backend.Stackingproof.html#index_valid">index_valid</a> [definition, in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="backend.Stackingproof.html#index_val_init_frame">index_val_init_frame</a> [lemma, in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="backend.Parallelmove.html#Indst_noOverlap_aux">Indst_noOverlap_aux</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#Ingetsrc_swap">Ingetsrc_swap</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#Ingetsrc_swap2">Ingetsrc_swap2</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="lib.Maps.html#init">init</a> [definition, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="backend.Locations.html#init">init</a> [definition, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="lib.Maps.html#init">init</a> [definition, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#init">init</a> [definition, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="backend.Kildall.html#initial_state_invariant">initial_state_invariant</a> [lemma, in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Globalenvs.html#initmem_nullptr">initmem_nullptr</a> [lemma, in <a href="backend.Globalenvs.html">backend.Globalenvs</a>]<br/>
-<a href="backend.Globalenvs.html#initmem_undef">initmem_undef</a> [lemma, in <a href="backend.Globalenvs.html">backend.Globalenvs</a>]<br/>
-<a href="backend.Machabstr.html#init_frame">init_frame</a> [definition, in <a href="backend.Machabstr.html">backend.Machabstr</a>]<br/>
-<a href="backend.RTLgen.html#init_mapping">init_mapping</a> [definition, in <a href="backend.RTLgen.html">backend.RTLgen</a>]<br/>
-<a href="backend.RTLgenproof1.html#init_mapping_wf">init_mapping_wf</a> [lemma, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.Globalenvs.html#init_mem">init_mem</a> [definition, in <a href="backend.Globalenvs.html">backend.Globalenvs</a>]<br/>
-<a href="backend.Globalenvs.html#init_mem_transf">init_mem_transf</a> [lemma, in <a href="backend.Globalenvs.html">backend.Globalenvs</a>]<br/>
-<a href="backend.Globalenvs.html#init_mem_transf_partial">init_mem_transf_partial</a> [lemma, in <a href="backend.Globalenvs.html">backend.Globalenvs</a>]<br/>
-<a href="backend.RTL.html#init_regs">init_regs</a> [definition, in <a href="backend.RTL.html">backend.RTL</a>]<br/>
-<a href="backend.RTLgen.html#init_state">init_state</a> [definition, in <a href="backend.RTLgen.html">backend.RTLgen</a>]<br/>
-<a href="backend.RTLgen.html#init_state_wf">init_state_wf</a> [lemma, in <a href="backend.RTLgen.html">backend.RTLgen</a>]<br/>
-<a href="lib.Lattice.html#Inj">Inj</a> [constructor, in <a href="lib.Lattice.html">lib.Lattice</a>]<br/>
-<a href="backend.Mem.html#inject_incr">inject_incr</a> [definition, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#inject_incr_refl">inject_incr_refl</a> [lemma, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#inject_incr_trans">inject_incr_trans</a> [lemma, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.RTL.html#Inop">Inop</a> [constructor, in <a href="backend.RTL.html">backend.RTL</a>]<br/>
-<a href="lib.Inclusion.html#insert_bin">insert_bin</a> [definition, in <a href="lib.Inclusion.html">lib.Inclusion</a>]<br/>
-<a href="lib.Inclusion.html#insert_bin_included">insert_bin_included</a> [lemma, in <a href="lib.Inclusion.html">lib.Inclusion</a>]<br/>
-<a href="backend.Cmconstrproof.html#insert_lenv">insert_lenv</a> [inductive, in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#insert_lenv_lookup1">insert_lenv_lookup1</a> [lemma, in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#insert_lenv_lookup2">insert_lenv_lookup2</a> [lemma, in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#insert_lenv_S">insert_lenv_S</a> [constructor, in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#insert_lenv_0">insert_lenv_0</a> [constructor, in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Linear.html#instruction">instruction</a> [inductive, in <a href="backend.Linear.html">backend.Linear</a>]<br/>
-<a href="backend.PPC.html#instruction">instruction</a> [inductive, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.RTL.html#instruction">instruction</a> [inductive, in <a href="backend.RTL.html">backend.RTL</a>]<br/>
-<a href="backend.Mach.html#instruction">instruction</a> [inductive, in <a href="backend.Mach.html">backend.Mach</a>]<br/>
-<a href="backend.RTLgenproof1.html#instr_at_incr">instr_at_incr</a> [lemma, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="lib.Integers.html#int">int</a> [inductive, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#Int">Int</a> [module, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html">Integers</a> [library]<br/>
-<a href="backend.InterfGraph.html#interfere">interfere</a> [definition, in <a href="backend.InterfGraph.html">backend.InterfGraph</a>]<br/>
-<a href="backend.Coloringproof.html#interfere_incl">interfere_incl</a> [lemma, in <a href="backend.Coloringproof.html">backend.Coloringproof</a>]<br/>
-<a href="backend.InterfGraph.html#interfere_mreg">interfere_mreg</a> [definition, in <a href="backend.InterfGraph.html">backend.InterfGraph</a>]<br/>
-<a href="backend.Coloringproof.html#interfere_mreg_incl">interfere_mreg_incl</a> [lemma, in <a href="backend.Coloringproof.html">backend.Coloringproof</a>]<br/>
-<a href="backend.InterfGraph.html#interfere_sym">interfere_sym</a> [lemma, in <a href="backend.InterfGraph.html">backend.InterfGraph</a>]<br/>
-<a href="backend.InterfGraph.html">InterfGraph</a> [library]<br/>
-<a href="backend.Coloring.html#interf_graph">interf_graph</a> [definition, in <a href="backend.Coloring.html">backend.Coloring</a>]<br/>
-<a href="backend.Coloringproof.html#interf_graph_correct_1">interf_graph_correct_1</a> [lemma, in <a href="backend.Coloringproof.html">backend.Coloringproof</a>]<br/>
-<a href="backend.Coloringproof.html#interf_graph_correct_2">interf_graph_correct_2</a> [lemma, in <a href="backend.Coloringproof.html">backend.Coloringproof</a>]<br/>
-<a href="backend.Coloringproof.html#interf_graph_correct_3">interf_graph_correct_3</a> [lemma, in <a href="backend.Coloringproof.html">backend.Coloringproof</a>]<br/>
-<a href="backend.Cmconstr.html#intoffloat">intoffloat</a> [definition, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="lib.Floats.html#intoffloat">intoffloat</a> [axiom, in <a href="lib.Floats.html">lib.Floats</a>]<br/>
-<a href="backend.Values.html#intoffloat">intoffloat</a> [definition, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Constprop.html#intval">intval</a> [definition, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constpropproof.html#intval_correct">intval_correct</a> [lemma, in <a href="backend.Constpropproof.html">backend.Constpropproof</a>]<br/>
-<a href="backend.Machabstr2mach.html#int_add_no_overflow">int_add_no_overflow</a> [lemma, in <a href="backend.Machabstr2mach.html">backend.Machabstr2mach</a>]<br/>
-<a href="backend.Lineartyping.html#int_callee_save">int_callee_save</a> [definition, in <a href="backend.Lineartyping.html">backend.Lineartyping</a>]<br/>
-<a href="backend.Linearizetyping.html#int_callee_save_bound">int_callee_save_bound</a> [lemma, in <a href="backend.Linearizetyping.html">backend.Linearizetyping</a>]<br/>
-<a href="backend.Conventions.html#int_callee_save_norepet">int_callee_save_norepet</a> [lemma, in <a href="backend.Conventions.html">backend.Conventions</a>]<br/>
-<a href="backend.Conventions.html#int_callee_save_not_destroyed">int_callee_save_not_destroyed</a> [lemma, in <a href="backend.Conventions.html">backend.Conventions</a>]<br/>
-<a href="backend.Conventions.html#int_callee_save_regs">int_callee_save_regs</a> [definition, in <a href="backend.Conventions.html">backend.Conventions</a>]<br/>
-<a href="backend.Conventions.html#int_callee_save_type">int_callee_save_type</a> [lemma, in <a href="backend.Conventions.html">backend.Conventions</a>]<br/>
-<a href="backend.Conventions.html#int_float_callee_save_disjoint">int_float_callee_save_disjoint</a> [lemma, in <a href="backend.Conventions.html">backend.Conventions</a>]<br/>
-<a href="backend.Lineartyping.html#int_local">int_local</a> [definition, in <a href="backend.Lineartyping.html">backend.Lineartyping</a>]<br/>
-<a href="backend.Linearizetyping.html#int_local_slot_bound">int_local_slot_bound</a> [lemma, in <a href="backend.Linearizetyping.html">backend.Linearizetyping</a>]<br/>
-<a href="lib.Integers.html#int_of_one_bits">int_of_one_bits</a> [definition, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Conventions.html#int_param_regs">int_param_regs</a> [definition, in <a href="backend.Conventions.html">backend.Conventions</a>]<br/>
-<a href="backend.Cmconstrproof.html#inv_eval_Eop_0">inv_eval_Eop_0</a> [lemma, in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#inv_eval_Eop_1">inv_eval_Eop_1</a> [lemma, in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#inv_eval_Eop_2">inv_eval_Eop_2</a> [lemma, in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Mem.html#in_bounds">in_bounds</a> [definition, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#in_bounds_exten">in_bounds_exten</a> [lemma, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#in_bounds_holds">in_bounds_holds</a> [lemma, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#in_bounds_inject">in_bounds_inject</a> [lemma, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Allocproof_aux.html#in_cons_noteq">in_cons_noteq</a> [lemma, in <a href="backend.Allocproof_aux.html">backend.Allocproof_aux</a>]<br/>
-<a href="backend.Kildall.html#in_incr">in_incr</a> [definition, in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Kildall.html#in_incr_refl">in_incr_refl</a> [lemma, in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Kildall.html#in_incr_trans">in_incr_trans</a> [lemma, in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Parallelmove.html#In_Indst">In_Indst</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Alloctyping_aux.html#in_move__in_srcdst">in_move__in_srcdst</a> [lemma, in <a href="backend.Alloctyping_aux.html">backend.Alloctyping_aux</a>]<br/>
-<a href="backend.Allocproof_aux.html#In_norepet">In_norepet</a> [lemma, in <a href="backend.Allocproof_aux.html">backend.Allocproof_aux</a>]<br/>
-<a href="backend.Locations.html#in_notin_diff">in_notin_diff</a> [lemma, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Parallelmove.html#In_noTmp_notempo">In_noTmp_notempo</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="lib.Inclusion.html#in_or_insert_bin">in_or_insert_bin</a> [lemma, in <a href="lib.Inclusion.html">lib.Inclusion</a>]<br/>
-<a href="backend.Machabstr2mach.html#in_or_notin_callstack">in_or_notin_callstack</a> [lemma, in <a href="backend.Machabstr2mach.html">backend.Machabstr2mach</a>]<br/>
-<a href="lib.Inclusion.html#In_permute_app_head">In_permute_app_head</a> [lemma, in <a href="lib.Inclusion.html">lib.Inclusion</a>]<br/>
-<a href="lib.Integers.html#in_range">in_range</a> [definition, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#in_range_range">in_range_range</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Inclusion.html#in_remove_head">in_remove_head</a> [lemma, in <a href="lib.Inclusion.html">lib.Inclusion</a>]<br/>
-<a href="backend.Parallelmove.html#In_SD_diff">In_SD_diff</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#In_SD_diff'">In_SD_diff'</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#In_SD_no_o">In_SD_no_o</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Alloctyping_aux.html#in_split_move">in_split_move</a> [lemma, in <a href="backend.Alloctyping_aux.html">backend.Alloctyping_aux</a>]<br/>
-<a href="lib.Maps.html#in_xelements">in_xelements</a> [lemma, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#in_xkeys">in_xkeys</a> [lemma, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="backend.PPC.html#IR">IR</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#ireg">ireg</a> [inductive, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#ireg_eq">ireg_eq</a> [lemma, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPCgen.html#ireg_of">ireg_of</a> [definition, in <a href="backend.PPCgen.html">backend.PPCgen</a>]<br/>
-<a href="backend.PPCgenproof1.html#ireg_of_is_data_reg">ireg_of_is_data_reg</a> [lemma, in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.PPCgenproof1.html#ireg_of_not_GPR1">ireg_of_not_GPR1</a> [lemma, in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.PPCgenproof1.html#ireg_of_not_GPR2">ireg_of_not_GPR2</a> [lemma, in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.PPCgenproof1.html#ireg_val">ireg_val</a> [lemma, in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.Values.html#isfalse_not_istrue">isfalse_not_istrue</a> [lemma, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Values.html#istrue_not_isfalse">istrue_not_isfalse</a> [lemma, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Kildall.html#is_basic_block_head">is_basic_block_head</a> [definition, in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Values.html#is_bool">is_bool</a> [definition, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.PPCgenproof1.html#is_data_reg">is_data_reg</a> [definition, in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="lib.Integers.html#is_false">is_false</a> [definition, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Values.html#is_false">is_false</a> [definition, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Tunneling.html#is_goto_block">is_goto_block</a> [definition, in <a href="backend.Tunneling.html">backend.Tunneling</a>]<br/>
-<a href="backend.Tunnelingproof.html#is_goto_block_correct">is_goto_block_correct</a> [lemma, in <a href="backend.Tunnelingproof.html">backend.Tunnelingproof</a>]<br/>
-<a href="backend.PPC.html#is_label">is_label</a> [definition, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.Mach.html#is_label">is_label</a> [definition, in <a href="backend.Mach.html">backend.Mach</a>]<br/>
-<a href="backend.Linear.html#is_label">is_label</a> [definition, in <a href="backend.Linear.html">backend.Linear</a>]<br/>
-<a href="backend.PPC.html#is_label_correct">is_label_correct</a> [lemma, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.Mach.html#is_label_correct">is_label_correct</a> [lemma, in <a href="backend.Mach.html">backend.Mach</a>]<br/>
-<a href="backend.Linear.html#is_label_correct">is_label_correct</a> [lemma, in <a href="backend.Linear.html">backend.Linear</a>]<br/>
-<a href="backend.Op.html#is_move_operation">is_move_operation</a> [definition, in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Op.html#is_move_operation_correct">is_move_operation_correct</a> [lemma, in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="lib.Integers.html#is_power2">is_power2</a> [definition, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#is_power2_correct">is_power2_correct</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#is_power2_range">is_power2_range</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#is_power2_rng">is_power2_rng</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#is_rlw_mask">is_rlw_mask</a> [definition, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#is_rlw_mask_rec">is_rlw_mask_rec</a> [definition, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Linearizeproof.html#is_tail">is_tail</a> [inductive, in <a href="backend.Linearizeproof.html">backend.Linearizeproof</a>]<br/>
-<a href="backend.Linearizeproof.html#is_tail_cons">is_tail_cons</a> [constructor, in <a href="backend.Linearizeproof.html">backend.Linearizeproof</a>]<br/>
-<a href="backend.Linearizeproof.html#is_tail_cons_left">is_tail_cons_left</a> [lemma, in <a href="backend.Linearizeproof.html">backend.Linearizeproof</a>]<br/>
-<a href="backend.Linearizeproof.html#is_tail_exec_instr">is_tail_exec_instr</a> [lemma, in <a href="backend.Linearizeproof.html">backend.Linearizeproof</a>]<br/>
-<a href="backend.Linearizeproof.html#is_tail_exec_instrs">is_tail_exec_instrs</a> [lemma, in <a href="backend.Linearizeproof.html">backend.Linearizeproof</a>]<br/>
-<a href="backend.Linearizeproof.html#is_tail_find_label">is_tail_find_label</a> [lemma, in <a href="backend.Linearizeproof.html">backend.Linearizeproof</a>]<br/>
-<a href="backend.Linearizeproof.html#is_tail_in">is_tail_in</a> [lemma, in <a href="backend.Linearizeproof.html">backend.Linearizeproof</a>]<br/>
-<a href="backend.Linearizeproof.html#is_tail_refl">is_tail_refl</a> [constructor, in <a href="backend.Linearizeproof.html">backend.Linearizeproof</a>]<br/>
-<a href="backend.CSE.html#is_trivial_op">is_trivial_op</a> [definition, in <a href="backend.CSE.html">backend.CSE</a>]<br/>
-<a href="lib.Integers.html#is_true">is_true</a> [definition, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Values.html#is_true">is_true</a> [definition, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Kildall.html#iterate">iterate</a> [definition, in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Kildall.html#iterate_base">iterate_base</a> [lemma, in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Kildall.html#iterate_incr">iterate_incr</a> [lemma, in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Kildall.html#iterate_solution">iterate_solution</a> [lemma, in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Kildall.html#iterate_step">iterate_step</a> [lemma, in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Kildall.html#iter_step">iter_step</a> [definition, in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Locations.html#IT1">IT1</a> [constructor, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#IT2">IT2</a> [constructor, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#IT3">IT3</a> [constructor, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<br/><br/><a name="global_K"></a><h2>K </h2>
-<a href="backend.Kildall.html">Kildall</a> [library]<br/>
-<a href="backend.CSE.html#kill_loads">kill_loads</a> [definition, in <a href="backend.CSE.html">backend.CSE</a>]<br/>
-<a href="backend.CSE.html#kill_load_eqs">kill_load_eqs</a> [definition, in <a href="backend.CSE.html">backend.CSE</a>]<br/>
-<a href="backend.CSEproof.html#kill_load_eqs_incl">kill_load_eqs_incl</a> [lemma, in <a href="backend.CSEproof.html">backend.CSEproof</a>]<br/>
-<a href="backend.CSEproof.html#kill_load_eqs_ops">kill_load_eqs_ops</a> [lemma, in <a href="backend.CSEproof.html">backend.CSEproof</a>]<br/>
-<a href="backend.CSEproof.html#kill_load_satisfiable">kill_load_satisfiable</a> [lemma, in <a href="backend.CSEproof.html">backend.CSEproof</a>]<br/>
-<br/><br/><a name="global_L"></a><h2>L </h2>
-<a href="backend.Kildall.html#L">L</a> [module, in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Kildall.html#L">L</a> [module, in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Kildall.html#L">L</a> [module, in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Kildall.html#L">L</a> [module, in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Kildall.html#L">L</a> [module, in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Kildall.html#L">L</a> [module, in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Kildall.html#L">L</a> [module, in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Kildall.html#L">L</a> [module, in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Kildall.html#L">L</a> [module, in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Linear.html#label">label</a> [definition, in <a href="backend.Linear.html">backend.Linear</a>]<br/>
-<a href="backend.PPC.html#label">label</a> [definition, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.Mach.html#label">label</a> [definition, in <a href="backend.Mach.html">backend.Mach</a>]<br/>
-<a href="backend.Linearizeproof.html#label_in_lin_block">label_in_lin_block</a> [lemma, in <a href="backend.Linearizeproof.html">backend.Linearizeproof</a>]<br/>
-<a href="backend.Linearizeproof.html#label_in_lin_rec">label_in_lin_rec</a> [lemma, in <a href="backend.Linearizeproof.html">backend.Linearizeproof</a>]<br/>
-<a href="backend.PPC.html#label_pos">label_pos</a> [definition, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPCgenproof.html#label_pos_code_tail">label_pos_code_tail</a> [lemma, in <a href="backend.PPCgenproof.html">backend.PPCgenproof</a>]<br/>
-<a href="backend.Parallelmove.html#last">last</a> [definition, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#last_app">last_app</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#last_cons">last_cons</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#last_replace">last_replace</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="lib.Lattice.html">Lattice</a> [library]<br/>
-<a href="backend.Linearize.html#lbl">lbl</a> [definition, in <a href="backend.Linearize.html">backend.Linearize</a>]<br/>
-<a href="backend.Linearize.html#lbl">lbl</a> [definition, in <a href="backend.Linearize.html">backend.Linearize</a>]<br/>
-<a href="lib.Lattice.html#LBoolean">LBoolean</a> [module, in <a href="lib.Lattice.html">lib.Lattice</a>]<br/>
-<a href="backend.Linear.html#Lcall">Lcall</a> [constructor, in <a href="backend.Linear.html">backend.Linear</a>]<br/>
-<a href="backend.Linear.html#Lcond">Lcond</a> [constructor, in <a href="backend.Linear.html">backend.Linear</a>]<br/>
-<a href="lib.Maps.html#Leaf">Leaf</a> [constructor, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Inclusion.html#leaf">leaf</a> [definition, in <a href="lib.Inclusion.html">lib.Inclusion</a>]<br/>
-<a href="lib.Inclusion.html#leaf">leaf</a> [constructor, in <a href="lib.Inclusion.html">lib.Inclusion</a>]<br/>
-<a href="lib.Inclusion.html#leaf">leaf</a> [definition, in <a href="lib.Inclusion.html">lib.Inclusion</a>]<br/>
-<a href="lib.Inclusion.html#leaf">leaf</a> [definition, in <a href="lib.Inclusion.html">lib.Inclusion</a>]<br/>
-<a href="backend.Allocproof.html#length_addr_args">length_addr_args</a> [lemma, in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.Parallelmove.html#length_app">length_app</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Allocproof.html#length_cond_args">length_cond_args</a> [lemma, in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.Allocproof.html#length_op_args">length_op_args</a> [lemma, in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.Parallelmove.html#length_replace">length_replace</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Cminor.html#letenv">letenv</a> [definition, in <a href="backend.Cminor.html">backend.Cminor</a>]<br/>
-<a href="backend.Csharpminor.html#letenv">letenv</a> [definition, in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.RTLtyping.html#let_fold_args_res">let_fold_args_res</a> [lemma, in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="lib.Lattice.html#LFlat">LFlat</a> [module, in <a href="lib.Lattice.html">lib.Lattice</a>]<br/>
-<a href="backend.Linear.html#Lgetstack">Lgetstack</a> [constructor, in <a href="backend.Linear.html">backend.Linear</a>]<br/>
-<a href="backend.Linear.html#Lgoto">Lgoto</a> [constructor, in <a href="backend.Linear.html">backend.Linear</a>]<br/>
-<a href="backend.Cmconstr.html#lift">lift</a> [definition, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#lift_condexpr">lift_condexpr</a> [definition, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#lift_expr">lift_expr</a> [definition, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#lift_exprlist">lift_exprlist</a> [definition, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Linear.html">Linear</a> [library]<br/>
-<a href="backend.Linearize.html">Linearize</a> [library]<br/>
-<a href="backend.Linearizeproof.html">Linearizeproof</a> [library]<br/>
-<a href="backend.Linearizetyping.html">Linearizetyping</a> [library]<br/>
-<a href="backend.Linearize.html#linearize_block">linearize_block</a> [definition, in <a href="backend.Linearize.html">backend.Linearize</a>]<br/>
-<a href="backend.Linearizetyping.html#linearize_block_incl">linearize_block_incl</a> [lemma, in <a href="backend.Linearizetyping.html">backend.Linearizetyping</a>]<br/>
-<a href="backend.Linearize.html#linearize_body">linearize_body</a> [definition, in <a href="backend.Linearize.html">backend.Linearize</a>]<br/>
-<a href="backend.Linearize.html#linearize_function">linearize_function</a> [definition, in <a href="backend.Linearize.html">backend.Linearize</a>]<br/>
-<a href="backend.Lineartyping.html">Lineartyping</a> [library]<br/>
-<a href="backend.Machtyping.html#link_invariant">link_invariant</a> [definition, in <a href="backend.Machtyping.html">backend.Machtyping</a>]<br/>
-<a href="backend.Parallelmove.html#listsLoc2Moves">listsLoc2Moves</a> [definition, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Allocation.html#listsLoc2Moves">listsLoc2Moves</a> [definition, in <a href="backend.Allocation.html">backend.Allocation</a>]<br/>
-<a href="lib.Coqlib.html#list_append_map">list_append_map</a> [lemma, in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#list_disjoint">list_disjoint</a> [definition, in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#list_disjoint_cons_left">list_disjoint_cons_left</a> [lemma, in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#list_disjoint_cons_right">list_disjoint_cons_right</a> [lemma, in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#list_disjoint_notin">list_disjoint_notin</a> [lemma, in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#list_disjoint_sym">list_disjoint_sym</a> [lemma, in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#list_forall2">list_forall2</a> [inductive, in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#list_forall2_cons">list_forall2_cons</a> [constructor, in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#list_forall2_imply">list_forall2_imply</a> [lemma, in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#list_forall2_nil">list_forall2_nil</a> [constructor, in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#list_in_map_inv">list_in_map_inv</a> [lemma, in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#list_length_map">list_length_map</a> [lemma, in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#list_map_compose">list_map_compose</a> [lemma, in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#list_map_exten">list_map_exten</a> [lemma, in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#list_map_norepet">list_map_norepet</a> [lemma, in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#list_map_nth">list_map_nth</a> [lemma, in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#list_norepet">list_norepet</a> [inductive, in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#list_norepet_append">list_norepet_append</a> [lemma, in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#list_norepet_append_left">list_norepet_append_left</a> [lemma, in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#list_norepet_append_right">list_norepet_append_right</a> [lemma, in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#list_norepet_cons">list_norepet_cons</a> [constructor, in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#list_norepet_dec">list_norepet_dec</a> [lemma, in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#list_norepet_nil">list_norepet_nil</a> [constructor, in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="backend.Allocproof.html#live0">live0</a> [definition, in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.Linear.html#Llabel">Llabel</a> [constructor, in <a href="backend.Linear.html">backend.Linear</a>]<br/>
-<a href="backend.Linear.html#Lload">Lload</a> [constructor, in <a href="backend.Linear.html">backend.Linear</a>]<br/>
-<a href="backend.Mem.html#load">load</a> [definition, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Cmconstr.html#load">load</a> [definition, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.CSE.html#Load">Load</a> [constructor, in <a href="backend.CSE.html">backend.CSE</a>]<br/>
-<a href="backend.PPCgen.html#loadimm">loadimm</a> [definition, in <a href="backend.PPCgen.html">backend.PPCgen</a>]<br/>
-<a href="backend.PPCgenproof1.html#loadimm_correct">loadimm_correct</a> [lemma, in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.PPCgen.html#loadind">loadind</a> [definition, in <a href="backend.PPCgen.html">backend.PPCgen</a>]<br/>
-<a href="backend.PPCgen.html#loadind_aux">loadind_aux</a> [definition, in <a href="backend.PPCgen.html">backend.PPCgen</a>]<br/>
-<a href="backend.PPCgenproof1.html#loadind_aux_correct">loadind_aux_correct</a> [lemma, in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.PPCgenproof1.html#loadind_correct">loadind_correct</a> [lemma, in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.Mem.html#loadv">loadv</a> [definition, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#loadv_inject">loadv_inject</a> [lemma, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.PPCgenproof.html#loadv_8_signed_unsigned">loadv_8_signed_unsigned</a> [lemma, in <a href="backend.PPCgenproof.html">backend.PPCgenproof</a>]<br/>
-<a href="backend.PPC.html#load1">load1</a> [definition, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#load2">load2</a> [definition, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.Mem.html#load_agree">load_agree</a> [lemma, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#load_alloc_other">load_alloc_other</a> [lemma, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#load_alloc_same">load_alloc_same</a> [lemma, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#load_contentmap_agree">load_contentmap_agree</a> [lemma, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#load_contents">load_contents</a> [definition, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#load_contents_init">load_contents_init</a> [lemma, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#load_contents_inject">load_contents_inject</a> [lemma, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#load_extends">load_extends</a> [lemma, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#load_free">load_free</a> [lemma, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Cminorgenproof.html#load_freelist">load_freelist</a> [lemma, in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#load_from_alloc_is_undef">load_from_alloc_is_undef</a> [lemma, in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Mem.html#load_inject">load_inject</a> [lemma, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#load_inv">load_inv</a> [lemma, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#load_in_bounds">load_in_bounds</a> [lemma, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Values.html#load_result">load_result</a> [definition, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Cminorgenproof.html#load_result_idem">load_result_idem</a> [lemma, in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Mem.html#load_result_inject">load_result_inject</a> [lemma, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Cminorgenproof.html#load_result_normalized">load_result_normalized</a> [lemma, in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Machabstr2mach.html#load_result_ty">load_result_ty</a> [lemma, in <a href="backend.Machabstr2mach.html">backend.Machabstr2mach</a>]<br/>
-<a href="backend.Mach.html#load_stack">load_stack</a> [definition, in <a href="backend.Mach.html">backend.Mach</a>]<br/>
-<a href="backend.Mem.html#load_store_contents_mismatch">load_store_contents_mismatch</a> [lemma, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#load_store_contents_other">load_store_contents_other</a> [lemma, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#load_store_contents_overlap">load_store_contents_overlap</a> [lemma, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#load_store_contents_same">load_store_contents_same</a> [lemma, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#load_store_other">load_store_other</a> [lemma, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#load_store_same">load_store_same</a> [lemma, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Locations.html#loc">loc</a> [inductive, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#Loc">Loc</a> [module, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#Local">Local</a> [constructor, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Csharpminor.html#local_variable">local_variable</a> [inductive, in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Locations.html">Locations</a> [library]<br/>
-<a href="backend.Locations.html#Locmap">Locmap</a> [module, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.LTL.html#locset">locset</a> [definition, in <a href="backend.LTL.html">backend.LTL</a>]<br/>
-<a href="backend.Linear.html#locset">locset</a> [definition, in <a href="backend.Linear.html">backend.Linear</a>]<br/>
-<a href="backend.Conventions.html#locs_acceptable">locs_acceptable</a> [definition, in <a href="backend.Conventions.html">backend.Conventions</a>]<br/>
-<a href="backend.Conventions.html#locs_acceptable_disj_temporaries">locs_acceptable_disj_temporaries</a> [lemma, in <a href="backend.Conventions.html">backend.Conventions</a>]<br/>
-<a href="backend.Alloctyping.html#locs_read_ok">locs_read_ok</a> [definition, in <a href="backend.Alloctyping.html">backend.Alloctyping</a>]<br/>
-<a href="backend.Alloctyping.html#locs_write_ok">locs_write_ok</a> [definition, in <a href="backend.Alloctyping.html">backend.Alloctyping</a>]<br/>
-<a href="backend.Conventions.html#loc_acceptable">loc_acceptable</a> [definition, in <a href="backend.Conventions.html">backend.Conventions</a>]<br/>
-<a href="backend.Allocproof.html#loc_acceptable_noteq_diff">loc_acceptable_noteq_diff</a> [lemma, in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.Allocproof.html#loc_acceptable_notin_notin">loc_acceptable_notin_notin</a> [lemma, in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.Conventions.html#loc_arguments">loc_arguments</a> [definition, in <a href="backend.Conventions.html">backend.Conventions</a>]<br/>
-<a href="backend.Conventions.html#loc_arguments_acceptable">loc_arguments_acceptable</a> [lemma, in <a href="backend.Conventions.html">backend.Conventions</a>]<br/>
-<a href="backend.Conventions.html#loc_arguments_bounded">loc_arguments_bounded</a> [lemma, in <a href="backend.Conventions.html">backend.Conventions</a>]<br/>
-<a href="backend.Conventions.html#loc_arguments_length">loc_arguments_length</a> [lemma, in <a href="backend.Conventions.html">backend.Conventions</a>]<br/>
-<a href="backend.Conventions.html#loc_arguments_norepet">loc_arguments_norepet</a> [lemma, in <a href="backend.Conventions.html">backend.Conventions</a>]<br/>
-<a href="backend.Conventions.html#loc_arguments_not_temporaries">loc_arguments_not_temporaries</a> [lemma, in <a href="backend.Conventions.html">backend.Conventions</a>]<br/>
-<a href="backend.Conventions.html#loc_arguments_rec">loc_arguments_rec</a> [definition, in <a href="backend.Conventions.html">backend.Conventions</a>]<br/>
-<a href="backend.Conventions.html#loc_arguments_type">loc_arguments_type</a> [lemma, in <a href="backend.Conventions.html">backend.Conventions</a>]<br/>
-<a href="backend.Conventions.html#loc_argument_acceptable">loc_argument_acceptable</a> [definition, in <a href="backend.Conventions.html">backend.Conventions</a>]<br/>
-<a href="backend.Coloring.html#loc_is_acceptable">loc_is_acceptable</a> [definition, in <a href="backend.Coloring.html">backend.Coloring</a>]<br/>
-<a href="backend.Coloringproof.html#loc_is_acceptable_correct">loc_is_acceptable_correct</a> [lemma, in <a href="backend.Coloringproof.html">backend.Coloringproof</a>]<br/>
-<a href="backend.Conventions.html#loc_parameters">loc_parameters</a> [definition, in <a href="backend.Conventions.html">backend.Conventions</a>]<br/>
-<a href="backend.Conventions.html#loc_parameters_not_temporaries">loc_parameters_not_temporaries</a> [lemma, in <a href="backend.Conventions.html">backend.Conventions</a>]<br/>
-<a href="backend.Conventions.html#loc_parameters_type">loc_parameters_type</a> [lemma, in <a href="backend.Conventions.html">backend.Conventions</a>]<br/>
-<a href="backend.Alloctyping.html#loc_read_ok">loc_read_ok</a> [definition, in <a href="backend.Alloctyping.html">backend.Alloctyping</a>]<br/>
-<a href="backend.Conventions.html#loc_result">loc_result</a> [definition, in <a href="backend.Conventions.html">backend.Conventions</a>]<br/>
-<a href="backend.Conventions.html#loc_result_acceptable">loc_result_acceptable</a> [lemma, in <a href="backend.Conventions.html">backend.Conventions</a>]<br/>
-<a href="backend.Conventions.html#loc_result_type">loc_result_type</a> [lemma, in <a href="backend.Conventions.html">backend.Conventions</a>]<br/>
-<a href="backend.Alloctyping.html#loc_write_ok">loc_write_ok</a> [definition, in <a href="backend.Alloctyping.html">backend.Alloctyping</a>]<br/>
-<a href="backend.Linear.html#Lop">Lop</a> [constructor, in <a href="backend.Linear.html">backend.Linear</a>]<br/>
-<a href="backend.Mem.html#low_bound">low_bound</a> [definition, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#low_bound_alloc">low_bound_alloc</a> [lemma, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#low_bound_free">low_bound_free</a> [lemma, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#low_bound_store">low_bound_store</a> [lemma, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.PPC.html#low_half_signed">low_half_signed</a> [axiom, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#low_half_signed_type">low_half_signed_type</a> [axiom, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#low_half_unsigned">low_half_unsigned</a> [axiom, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#low_half_unsigned_type">low_half_unsigned_type</a> [axiom, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#low_high_half_signed">low_high_half_signed</a> [axiom, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#low_high_half_unsigned">low_high_half_unsigned</a> [axiom, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPCgenproof1.html#low_high_s">low_high_s</a> [lemma, in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.PPCgenproof1.html#low_high_u">low_high_u</a> [lemma, in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.PPCgenproof1.html#low_high_u_xor">low_high_u_xor</a> [lemma, in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.PPCgen.html#low_s">low_s</a> [definition, in <a href="backend.PPCgen.html">backend.PPCgen</a>]<br/>
-<a href="backend.PPCgen.html#low_u">low_u</a> [definition, in <a href="backend.PPCgen.html">backend.PPCgen</a>]<br/>
-<a href="lib.Lattice.html#LPMap">LPMap</a> [module, in <a href="lib.Lattice.html">lib.Lattice</a>]<br/>
-<a href="backend.PPC.html#LR">LR</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.Linear.html#Lreturn">Lreturn</a> [constructor, in <a href="backend.Linear.html">backend.Linear</a>]<br/>
-<a href="backend.Linear.html#Lsetstack">Lsetstack</a> [constructor, in <a href="backend.Linear.html">backend.Linear</a>]<br/>
-<a href="backend.Linear.html#Lstore">Lstore</a> [constructor, in <a href="backend.Linear.html">backend.Linear</a>]<br/>
-<a href="lib.Integers.html#lt">lt</a> [definition, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Ordered.html#lt">lt</a> [definition, in <a href="lib.Ordered.html">lib.Ordered</a>]<br/>
-<a href="lib.Ordered.html#lt">lt</a> [definition, in <a href="lib.Ordered.html">lib.Ordered</a>]<br/>
-<a href="lib.Ordered.html#lt">lt</a> [definition, in <a href="lib.Ordered.html">lib.Ordered</a>]<br/>
-<a href="backend.LTL.html">LTL</a> [library]<br/>
-<a href="backend.LTLtyping.html">LTLtyping</a> [library]<br/>
-<a href="lib.Integers.html#ltu">ltu</a> [definition, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Ordered.html#lt_not_eq">lt_not_eq</a> [lemma, in <a href="lib.Ordered.html">lib.Ordered</a>]<br/>
-<a href="lib.Ordered.html#lt_not_eq">lt_not_eq</a> [lemma, in <a href="lib.Ordered.html">lib.Ordered</a>]<br/>
-<a href="lib.Ordered.html#lt_not_eq">lt_not_eq</a> [lemma, in <a href="lib.Ordered.html">lib.Ordered</a>]<br/>
-<a href="lib.Ordered.html#lt_trans">lt_trans</a> [lemma, in <a href="lib.Ordered.html">lib.Ordered</a>]<br/>
-<a href="lib.Ordered.html#lt_trans">lt_trans</a> [lemma, in <a href="lib.Ordered.html">lib.Ordered</a>]<br/>
-<a href="lib.Ordered.html#lt_trans">lt_trans</a> [lemma, in <a href="lib.Ordered.html">lib.Ordered</a>]<br/>
-<a href="lib.Lattice.html#lub">lub</a> [definition, in <a href="lib.Lattice.html">lib.Lattice</a>]<br/>
-<a href="lib.Lattice.html#lub">lub</a> [definition, in <a href="lib.Lattice.html">lib.Lattice</a>]<br/>
-<a href="lib.Sets.html#lub">lub</a> [definition, in <a href="lib.Sets.html">lib.Sets</a>]<br/>
-<a href="lib.Lattice.html#lub">lub</a> [definition, in <a href="lib.Lattice.html">lib.Lattice</a>]<br/>
-<a href="backend.Constprop.html#lub">lub</a> [definition, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="lib.Lattice.html#lub_commut">lub_commut</a> [lemma, in <a href="lib.Lattice.html">lib.Lattice</a>]<br/>
-<a href="backend.Constprop.html#lub_commut">lub_commut</a> [lemma, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="lib.Lattice.html#lub_commut">lub_commut</a> [lemma, in <a href="lib.Lattice.html">lib.Lattice</a>]<br/>
-<a href="lib.Sets.html#lub_commut">lub_commut</a> [lemma, in <a href="lib.Sets.html">lib.Sets</a>]<br/>
-<a href="lib.Lattice.html#lub_commut">lub_commut</a> [lemma, in <a href="lib.Lattice.html">lib.Lattice</a>]<br/>
-<a href="backend.Csharpminor.html#LVarray">LVarray</a> [constructor, in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Csharpminor.html#LVscalar">LVscalar</a> [constructor, in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<br/><br/><a name="global_M"></a><h2>M </h2>
-<a href="backend.Mach.html">Mach</a> [library]<br/>
-<a href="backend.Machabstr.html">Machabstr</a> [library]<br/>
-<a href="backend.Machabstr2mach.html">Machabstr2mach</a> [library]<br/>
-<a href="backend.Machtyping.html">Machtyping</a> [library]<br/>
-<a href="backend.Main.html">Main</a> [library]<br/>
-<a href="lib.Sets.html#MakeSet">MakeSet</a> [module, in <a href="lib.Sets.html">lib.Sets</a>]<br/>
-<a href="backend.Constprop.html#make_addimm">make_addimm</a> [definition, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constpropproof.html#make_addimm_correct">make_addimm_correct</a> [lemma, in <a href="backend.Constpropproof.html">backend.Constpropproof</a>]<br/>
-<a href="backend.Constprop.html#make_andimm">make_andimm</a> [definition, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constpropproof.html#make_andimm_correct">make_andimm_correct</a> [lemma, in <a href="backend.Constpropproof.html">backend.Constpropproof</a>]<br/>
-<a href="backend.Cminorgen.html#make_cast">make_cast</a> [definition, in <a href="backend.Cminorgen.html">backend.Cminorgen</a>]<br/>
-<a href="backend.Cminorgenproof.html#make_cast_correct">make_cast_correct</a> [lemma, in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Stacking.html#make_env">make_env</a> [definition, in <a href="backend.Stacking.html">backend.Stacking</a>]<br/>
-<a href="backend.Cminorgen.html#make_load">make_load</a> [definition, in <a href="backend.Cminorgen.html">backend.Cminorgen</a>]<br/>
-<a href="backend.Cminorgenproof.html#make_load_correct">make_load_correct</a> [lemma, in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Constprop.html#make_mulimm">make_mulimm</a> [definition, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constpropproof.html#make_mulimm_correct">make_mulimm_correct</a> [lemma, in <a href="backend.Constpropproof.html">backend.Constpropproof</a>]<br/>
-<a href="backend.Cminorgen.html#make_op">make_op</a> [definition, in <a href="backend.Cminorgen.html">backend.Cminorgen</a>]<br/>
-<a href="backend.Cminorgenproof.html#make_op_correct">make_op_correct</a> [lemma, in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Constprop.html#make_orimm">make_orimm</a> [definition, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constpropproof.html#make_orimm_correct">make_orimm_correct</a> [lemma, in <a href="backend.Constpropproof.html">backend.Constpropproof</a>]<br/>
-<a href="backend.Kildall.html#make_predecessors">make_predecessors</a> [definition, in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Kildall.html#make_predecessors_correct">make_predecessors_correct</a> [lemma, in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Constprop.html#make_shlimm">make_shlimm</a> [definition, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constpropproof.html#make_shlimm_correct">make_shlimm_correct</a> [lemma, in <a href="backend.Constpropproof.html">backend.Constpropproof</a>]<br/>
-<a href="backend.Constprop.html#make_shrimm">make_shrimm</a> [definition, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constpropproof.html#make_shrimm_correct">make_shrimm_correct</a> [lemma, in <a href="backend.Constpropproof.html">backend.Constpropproof</a>]<br/>
-<a href="backend.Constprop.html#make_shruimm">make_shruimm</a> [definition, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constpropproof.html#make_shruimm_correct">make_shruimm_correct</a> [lemma, in <a href="backend.Constpropproof.html">backend.Constpropproof</a>]<br/>
-<a href="backend.Cminorgen.html#make_stackaddr">make_stackaddr</a> [definition, in <a href="backend.Cminorgen.html">backend.Cminorgen</a>]<br/>
-<a href="backend.Cminorgenproof.html#make_stackaddr_correct">make_stackaddr_correct</a> [lemma, in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Cminorgen.html#make_store">make_store</a> [definition, in <a href="backend.Cminorgen.html">backend.Cminorgen</a>]<br/>
-<a href="backend.Cminorgenproof.html#make_store_correct">make_store_correct</a> [lemma, in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Constprop.html#make_xorimm">make_xorimm</a> [definition, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constpropproof.html#make_xorimm_correct">make_xorimm_correct</a> [lemma, in <a href="backend.Constpropproof.html">backend.Constpropproof</a>]<br/>
-<a href="lib.Maps.html#map">map</a> [definition, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#map">map</a> [definition, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#map">map</a> [definition, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#map">map</a> [definition, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#MAP">MAP</a> [module, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.union_find.html#MAP">MAP</a> [module, in <a href="lib.union_find.html">lib.union_find</a>]<br/>
-<a href="backend.RTLtyping.html#mapped">mapped</a> [definition, in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.RTLtyping.html#mapped_included_consistent">mapped_included_consistent</a> [lemma, in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.RTLtyping.html#mapped_list_included">mapped_list_included</a> [lemma, in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.RTLgen.html#mapping">mapping</a> [inductive, in <a href="backend.RTLgen.html">backend.RTLgen</a>]<br/>
-<a href="lib.Maps.html">Maps</a> [library]<br/>
-<a href="backend.Alloctyping_aux.html#map_f_getsrc_getdst">map_f_getsrc_getdst</a> [lemma, in <a href="backend.Alloctyping_aux.html">backend.Alloctyping_aux</a>]<br/>
-<a href="backend.Allocproof_aux.html#map_inv">map_inv</a> [lemma, in <a href="backend.Allocproof_aux.html">backend.Allocproof_aux</a>]<br/>
-<a href="backend.RTLgenproof1.html#map_wf">map_wf</a> [inductive, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#map_wf_incr">map_wf_incr</a> [lemma, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.Cminorgenproof.html#match_callstack">match_callstack</a> [inductive, in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#match_callstack_alloc_left">match_callstack_alloc_left</a> [lemma, in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#match_callstack_alloc_other">match_callstack_alloc_other</a> [lemma, in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#match_callstack_alloc_right">match_callstack_alloc_right</a> [lemma, in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#match_callstack_alloc_variables">match_callstack_alloc_variables</a> [lemma, in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#match_callstack_alloc_variables_rec">match_callstack_alloc_variables_rec</a> [lemma, in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#match_callstack_freelist">match_callstack_freelist</a> [lemma, in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#match_callstack_freelist_rec">match_callstack_freelist_rec</a> [lemma, in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#match_callstack_incr_bound">match_callstack_incr_bound</a> [lemma, in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#match_callstack_mapped">match_callstack_mapped</a> [lemma, in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#match_callstack_match_globalenvs">match_callstack_match_globalenvs</a> [lemma, in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#match_callstack_store_above">match_callstack_store_above</a> [lemma, in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#match_callstack_store_local">match_callstack_store_local</a> [lemma, in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#match_callstack_store_local_unchanged">match_callstack_store_local_unchanged</a> [lemma, in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#match_env">match_env</a> [inductive, in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.RTLgenproof1.html#match_env">match_env</a> [inductive, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.Cminorgenproof.html#match_env_alloc_other">match_env_alloc_other</a> [lemma, in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#match_env_alloc_same">match_env_alloc_same</a> [lemma, in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.RTLgenproof1.html#match_env_empty">match_env_empty</a> [lemma, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#match_env_exten">match_env_exten</a> [lemma, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.Cminorgenproof.html#match_env_extensional">match_env_extensional</a> [lemma, in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.RTLgenproof1.html#match_env_find_reg">match_env_find_reg</a> [lemma, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.Cminorgenproof.html#match_env_freelist">match_env_freelist</a> [lemma, in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.RTLgenproof1.html#match_env_invariant">match_env_invariant</a> [lemma, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#match_env_letvar">match_env_letvar</a> [lemma, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.Cminorgenproof.html#match_env_store_above">match_env_store_above</a> [lemma, in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#match_env_store_local">match_env_store_local</a> [lemma, in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#match_env_store_mapped">match_env_store_mapped</a> [lemma, in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.RTLgenproof1.html#match_env_update_temp">match_env_update_temp</a> [lemma, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#match_env_update_var">match_env_update_var</a> [lemma, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.Cminorgenproof.html#match_globalenvs">match_globalenvs</a> [inductive, in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#match_globalenvs_init">match_globalenvs_init</a> [lemma, in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.RTLgenproof1.html#match_init_env_init_reg">match_init_env_init_reg</a> [lemma, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof.html#match_return_outcome">match_return_outcome</a> [definition, in <a href="backend.RTLgenproof.html">backend.RTLgenproof</a>]<br/>
-<a href="backend.RTLgenproof.html#match_return_reg">match_return_reg</a> [definition, in <a href="backend.RTLgenproof.html">backend.RTLgenproof</a>]<br/>
-<a href="backend.RTLgenproof1.html#match_set_locals">match_set_locals</a> [lemma, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#match_set_params_init_regs">match_set_params_init_regs</a> [lemma, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.Cminorgenproof.html#match_var">match_var</a> [inductive, in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Lineartyping.html#max_over_instrs">max_over_instrs</a> [definition, in <a href="backend.Lineartyping.html">backend.Lineartyping</a>]<br/>
-<a href="backend.Linearizetyping.html#max_over_instrs_bound">max_over_instrs_bound</a> [lemma, in <a href="backend.Linearizetyping.html">backend.Linearizetyping</a>]<br/>
-<a href="backend.Lineartyping.html#max_over_list">max_over_list</a> [definition, in <a href="backend.Lineartyping.html">backend.Lineartyping</a>]<br/>
-<a href="backend.Linearizetyping.html#max_over_list_bound">max_over_list_bound</a> [lemma, in <a href="backend.Linearizetyping.html">backend.Linearizetyping</a>]<br/>
-<a href="backend.Lineartyping.html#max_over_list_pos">max_over_list_pos</a> [lemma, in <a href="backend.Lineartyping.html">backend.Lineartyping</a>]<br/>
-<a href="backend.Lineartyping.html#max_over_regs_of_funct">max_over_regs_of_funct</a> [definition, in <a href="backend.Lineartyping.html">backend.Lineartyping</a>]<br/>
-<a href="backend.Linearizetyping.html#max_over_regs_of_funct_bound">max_over_regs_of_funct_bound</a> [lemma, in <a href="backend.Linearizetyping.html">backend.Linearizetyping</a>]<br/>
-<a href="backend.Lineartyping.html#max_over_regs_of_funct_pos">max_over_regs_of_funct_pos</a> [lemma, in <a href="backend.Lineartyping.html">backend.Lineartyping</a>]<br/>
-<a href="backend.Lineartyping.html#max_over_regs_of_instr">max_over_regs_of_instr</a> [definition, in <a href="backend.Lineartyping.html">backend.Lineartyping</a>]<br/>
-<a href="backend.Lineartyping.html#max_over_slots_of_funct">max_over_slots_of_funct</a> [definition, in <a href="backend.Lineartyping.html">backend.Lineartyping</a>]<br/>
-<a href="backend.Linearizetyping.html#max_over_slots_of_funct_bound">max_over_slots_of_funct_bound</a> [lemma, in <a href="backend.Linearizetyping.html">backend.Linearizetyping</a>]<br/>
-<a href="backend.Lineartyping.html#max_over_slots_of_funct_pos">max_over_slots_of_funct_pos</a> [lemma, in <a href="backend.Lineartyping.html">backend.Lineartyping</a>]<br/>
-<a href="backend.Lineartyping.html#max_over_slots_of_instr">max_over_slots_of_instr</a> [definition, in <a href="backend.Lineartyping.html">backend.Lineartyping</a>]<br/>
-<a href="lib.Integers.html#max_signed">max_signed</a> [definition, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#max_unsigned">max_unsigned</a> [definition, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Mach.html#Mcall">Mcall</a> [constructor, in <a href="backend.Mach.html">backend.Mach</a>]<br/>
-<a href="backend.Mach.html#Mcond">Mcond</a> [constructor, in <a href="backend.Mach.html">backend.Mach</a>]<br/>
-<a href="backend.Cminorgenproof.html#mcs_cons">mcs_cons</a> [constructor, in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#mcs_nil">mcs_nil</a> [constructor, in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Mem.html#mem">mem</a> [inductive, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="lib.Sets.html#mem">mem</a> [definition, in <a href="lib.Sets.html">lib.Sets</a>]<br/>
-<a href="backend.Mem.html">Mem</a> [library]<br/>
-<a href="backend.RTLtyping.html#member">member</a> [definition, in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.RTLtyping.html#member_correct">member_correct</a> [lemma, in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.Mem.html#meminj">meminj</a> [definition, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.AST.html#memory_chunk">memory_chunk</a> [inductive, in <a href="backend.AST.html">backend.AST</a>]<br/>
-<a href="backend.Mem.html#memory_size">memory_size</a> [inductive, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Globalenvs.html#mem_add_globals_transf">mem_add_globals_transf</a> [lemma, in <a href="backend.Globalenvs.html">backend.Globalenvs</a>]<br/>
-<a href="lib.Sets.html#mem_add_other">mem_add_other</a> [lemma, in <a href="lib.Sets.html">lib.Sets</a>]<br/>
-<a href="lib.Sets.html#mem_add_same">mem_add_same</a> [lemma, in <a href="lib.Sets.html">lib.Sets</a>]<br/>
-<a href="backend.InterfGraph.html#mem_add_tail">mem_add_tail</a> [lemma, in <a href="backend.InterfGraph.html">backend.InterfGraph</a>]<br/>
-<a href="backend.Mem.html#mem_chunk">mem_chunk</a> [definition, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="lib.Sets.html#mem_empty">mem_empty</a> [lemma, in <a href="lib.Sets.html">lib.Sets</a>]<br/>
-<a href="backend.Mem.html#mem_exten">mem_exten</a> [lemma, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#mem_inject">mem_inject</a> [inductive, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="lib.Sets.html#mem_remove_other">mem_remove_other</a> [lemma, in <a href="lib.Sets.html">lib.Sets</a>]<br/>
-<a href="lib.Sets.html#mem_remove_same">mem_remove_same</a> [lemma, in <a href="lib.Sets.html">lib.Sets</a>]<br/>
-<a href="backend.Machabstr.html#mem_type">mem_type</a> [definition, in <a href="backend.Machabstr.html">backend.Machabstr</a>]<br/>
-<a href="lib.Sets.html#mem_union">mem_union</a> [lemma, in <a href="lib.Sets.html">lib.Sets</a>]<br/>
-<a href="backend.Parallelmove.html#mesure">mesure</a> [definition, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.AST.html#Mfloat32">Mfloat32</a> [constructor, in <a href="backend.AST.html">backend.AST</a>]<br/>
-<a href="backend.AST.html#Mfloat64">Mfloat64</a> [constructor, in <a href="backend.AST.html">backend.AST</a>]<br/>
-<a href="backend.Mach.html#Mgetparam">Mgetparam</a> [constructor, in <a href="backend.Mach.html">backend.Mach</a>]<br/>
-<a href="backend.Mach.html#Mgetstack">Mgetstack</a> [constructor, in <a href="backend.Mach.html">backend.Mach</a>]<br/>
-<a href="backend.Mach.html#Mgoto">Mgoto</a> [constructor, in <a href="backend.Mach.html">backend.Mach</a>]<br/>
-<a href="backend.AST.html#Mint16signed">Mint16signed</a> [constructor, in <a href="backend.AST.html">backend.AST</a>]<br/>
-<a href="backend.AST.html#Mint16unsigned">Mint16unsigned</a> [constructor, in <a href="backend.AST.html">backend.AST</a>]<br/>
-<a href="backend.AST.html#Mint32">Mint32</a> [constructor, in <a href="backend.AST.html">backend.AST</a>]<br/>
-<a href="backend.AST.html#Mint8signed">Mint8signed</a> [constructor, in <a href="backend.AST.html">backend.AST</a>]<br/>
-<a href="backend.AST.html#Mint8unsigned">Mint8unsigned</a> [constructor, in <a href="backend.AST.html">backend.AST</a>]<br/>
-<a href="lib.Integers.html#min_signed">min_signed</a> [definition, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#mkint_eq">mkint_eq</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.RTLtyping.html#mk_env">mk_env</a> [definition, in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.Mach.html#Mlabel">Mlabel</a> [constructor, in <a href="backend.Mach.html">backend.Mach</a>]<br/>
-<a href="backend.Mach.html#Mload">Mload</a> [constructor, in <a href="backend.Mach.html">backend.Mach</a>]<br/>
-<a href="lib.Integers.html#mods">mods</a> [definition, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Cmconstr.html#mods">mods</a> [definition, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Values.html#mods">mods</a> [definition, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="lib.Integers.html#mods_divs">mods_divs</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Values.html#mods_divs">mods_divs</a> [lemma, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="lib.Integers.html#modu">modu</a> [definition, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Values.html#modu">modu</a> [definition, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Cmconstr.html#modu">modu</a> [definition, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="lib.Integers.html#modulus">modulus</a> [definition, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#modulus_pos">modulus_pos</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#modu_and">modu_and</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#modu_divu">modu_divu</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Values.html#modu_divu">modu_divu</a> [lemma, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="lib.Integers.html#modu_divu_Euclid">modu_divu_Euclid</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Values.html#modu_pow2">modu_pow2</a> [lemma, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Cmconstr.html#mod_aux">mod_aux</a> [definition, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="lib.Integers.html#mod_in_range">mod_in_range</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.RTLgen.html#mon">mon</a> [definition, in <a href="backend.RTLgen.html">backend.RTLgen</a>]<br/>
-<a href="lib.Integers.html#mone">mone</a> [definition, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#mone_max_unsigned">mone_max_unsigned</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Mach.html#Mop">Mop</a> [constructor, in <a href="backend.Mach.html">backend.Mach</a>]<br/>
-<a href="backend.RTLgen.html#more_likely">more_likely</a> [axiom, in <a href="backend.RTLgen.html">backend.RTLgen</a>]<br/>
-<a href="backend.Parallelmove.html#Move">Move</a> [definition, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#Moves">Moves</a> [definition, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Alloctyping_aux.html#move_types_res">move_types_res</a> [lemma, in <a href="backend.Alloctyping_aux.html">backend.Alloctyping_aux</a>]<br/>
-<a href="backend.Alloctyping_aux.html#move_types_stepf">move_types_stepf</a> [lemma, in <a href="backend.Alloctyping_aux.html">backend.Alloctyping_aux</a>]<br/>
-<a href="backend.Locations.html#mreg">mreg</a> [inductive, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Lineartyping.html#mreg_bounded">mreg_bounded</a> [definition, in <a href="backend.Lineartyping.html">backend.Lineartyping</a>]<br/>
-<a href="backend.Locations.html#mreg_eq">mreg_eq</a> [lemma, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Linearizetyping.html#mreg_is_bounded">mreg_is_bounded</a> [lemma, in <a href="backend.Linearizetyping.html">backend.Linearizetyping</a>]<br/>
-<a href="backend.Locations.html#mreg_type">mreg_type</a> [definition, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Mach.html#Mreturn">Mreturn</a> [constructor, in <a href="backend.Mach.html">backend.Mach</a>]<br/>
-<a href="backend.Mach.html#Msetstack">Msetstack</a> [constructor, in <a href="backend.Mach.html">backend.Mach</a>]<br/>
-<a href="backend.Mach.html#Mstore">Mstore</a> [constructor, in <a href="backend.Mach.html">backend.Mach</a>]<br/>
-<a href="lib.Floats.html#mul">mul</a> [axiom, in <a href="lib.Floats.html">lib.Floats</a>]<br/>
-<a href="lib.Integers.html#mul">mul</a> [definition, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Cmconstr.html#mul">mul</a> [definition, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Values.html#mul">mul</a> [definition, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Cmconstr.html#mulf">mulf</a> [definition, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Values.html#mulf">mulf</a> [definition, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Cmconstr.html#mulimm">mulimm</a> [definition, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#mulimm_base">mulimm_base</a> [definition, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#mulimm_cases">mulimm_cases</a> [inductive, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#mulimm_case1">mulimm_case1</a> [constructor, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#mulimm_case2">mulimm_case2</a> [constructor, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#mulimm_default">mulimm_default</a> [constructor, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#mulimm_match">mulimm_match</a> [definition, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Kildall.html#multiple_predecessors">multiple_predecessors</a> [lemma, in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="lib.Integers.html#mul_add_distr_l">mul_add_distr_l</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Values.html#mul_add_distr_l">mul_add_distr_l</a> [lemma, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="lib.Integers.html#mul_add_distr_r">mul_add_distr_r</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Values.html#mul_add_distr_r">mul_add_distr_r</a> [lemma, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="lib.Integers.html#mul_assoc">mul_assoc</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Values.html#mul_assoc">mul_assoc</a> [lemma, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Cmconstr.html#mul_cases">mul_cases</a> [inductive, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#mul_case1">mul_case1</a> [constructor, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#mul_case2">mul_case2</a> [constructor, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Values.html#mul_commut">mul_commut</a> [lemma, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="lib.Integers.html#mul_commut">mul_commut</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Cmconstr.html#mul_default">mul_default</a> [constructor, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#mul_match">mul_match</a> [definition, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#mul_match_aux">mul_match_aux</a> [definition, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="lib.Integers.html#mul_one">mul_one</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#mul_pow2">mul_pow2</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Values.html#mul_pow2">mul_pow2</a> [lemma, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="lib.Integers.html#mul_zero">mul_zero</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.RTLgen.html#mutated_condexpr">mutated_condexpr</a> [definition, in <a href="backend.RTLgen.html">backend.RTLgen</a>]<br/>
-<a href="backend.RTLgen.html#mutated_expr">mutated_expr</a> [definition, in <a href="backend.RTLgen.html">backend.RTLgen</a>]<br/>
-<a href="backend.RTLgen.html#mutated_exprlist">mutated_exprlist</a> [definition, in <a href="backend.RTLgen.html">backend.RTLgen</a>]<br/>
-<a href="backend.RTLgenproof1.html#mutated_reg">mutated_reg</a> [definition, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#mutated_reg_in_map">mutated_reg_in_map</a> [lemma, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLtyping.html#mymap">mymap</a> [module, in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.RTLtyping.html#myreg">myreg</a> [module, in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.RTLtyping.html#myT">myT</a> [inductive, in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<br/><br/><a name="global_N"></a><h2>N </h2>
-<a href="backend.Op.html#n">n</a> [constructor, in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="lib.Inclusion.html#nat_le_bool">nat_le_bool</a> [definition, in <a href="lib.Inclusion.html">lib.Inclusion</a>]<br/>
-<a href="backend.Values.html#neg">neg</a> [definition, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="lib.Integers.html#neg">neg</a> [definition, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Floats.html#neg">neg</a> [axiom, in <a href="lib.Floats.html">lib.Floats</a>]<br/>
-<a href="backend.Values.html#negate_cmp">negate_cmp</a> [lemma, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="lib.Integers.html#negate_cmp">negate_cmp</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Values.html#negate_cmpf_eq">negate_cmpf_eq</a> [lemma, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="lib.Integers.html#negate_cmpu">negate_cmpu</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Values.html#negate_cmpu">negate_cmpu</a> [lemma, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Values.html#negate_cmp_mismatch">negate_cmp_mismatch</a> [lemma, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.AST.html#negate_comparison">negate_comparison</a> [definition, in <a href="backend.AST.html">backend.AST</a>]<br/>
-<a href="backend.Op.html#negate_condition">negate_condition</a> [definition, in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Values.html#negf">negf</a> [definition, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Cmconstr.html#negfloat">negfloat</a> [definition, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#negint">negint</a> [definition, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Values.html#neg_add_distr">neg_add_distr</a> [lemma, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="lib.Integers.html#neg_add_distr">neg_add_distr</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#neg_mul_distr_l">neg_mul_distr_l</a> [axiom, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#neg_mul_distr_r">neg_mul_distr_r</a> [axiom, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#neg_repr">neg_repr</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#neg_zero">neg_zero</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Values.html#neg_zero">neg_zero</a> [lemma, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Parallelmove.html#neq_is_neq">neq_is_neq</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.RTLgen.html#new_reg">new_reg</a> [definition, in <a href="backend.RTLgen.html">backend.RTLgen</a>]<br/>
-<a href="backend.RTLgenproof1.html#new_reg_fresh">new_reg_fresh</a> [lemma, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#new_reg_incr">new_reg_incr</a> [lemma, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#new_reg_not_in_map">new_reg_not_in_map</a> [lemma, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#new_reg_not_mutated">new_reg_not_mutated</a> [lemma, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#new_reg_return_ok">new_reg_return_ok</a> [lemma, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#new_reg_valid">new_reg_valid</a> [lemma, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.PPC.html#nextinstr">nextinstr</a> [definition, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPCgenproof1.html#nextinstr_inv">nextinstr_inv</a> [lemma, in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.PPCgenproof1.html#nextinstr_set_preg">nextinstr_set_preg</a> [lemma, in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.Parallelmove.html#nil">nil</a> [definition, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#nil">nil</a> [definition, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#nil">nil</a> [definition, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#nil">nil</a> [definition, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#nil">nil</a> [definition, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#nil">nil</a> [definition, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#nil">nil</a> [definition, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#nil">nil</a> [definition, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#nil">nil</a> [definition, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#nil">nil</a> [definition, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Allocproof_aux.html#nil">nil</a> [definition, in <a href="backend.Allocproof_aux.html">backend.Allocproof_aux</a>]<br/>
-<a href="backend.Parallelmove.html#nil">nil</a> [definition, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#nil">nil</a> [definition, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#nil">nil</a> [definition, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#nil">nil</a> [definition, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#nil">nil</a> [definition, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#nil">nil</a> [definition, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#nil">nil</a> [definition, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="lib.Maps.html#NIndexed">NIndexed</a> [module, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#NMap">NMap</a> [module, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#Node">Node</a> [constructor, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="backend.RTL.html#node">node</a> [definition, in <a href="backend.RTL.html">backend.RTL</a>]<br/>
-<a href="backend.LTL.html#node">node</a> [definition, in <a href="backend.LTL.html">backend.LTL</a>]<br/>
-<a href="lib.Inclusion.html#node">node</a> [constructor, in <a href="lib.Inclusion.html">lib.Inclusion</a>]<br/>
-<a href="backend.Locations.html#non_overlap_diff">non_overlap_diff</a> [lemma, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Parallelmove.html#NoOverlap">NoOverlap</a> [definition, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#noOverlap">noOverlap</a> [definition, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#noOverlapaux_insert">noOverlapaux_insert</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#noOverlapaux_swap2">noOverlapaux_swap2</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#noOverlap_aux">noOverlap_aux</a> [definition, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#noOverlap_auxpop">noOverlap_auxpop</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#noOverlap_auxPop">noOverlap_auxPop</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#noOverlap_aux_app">noOverlap_aux_app</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#noOverlap_Front0">noOverlap_Front0</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#noOverlap_head">noOverlap_head</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#noOverlap_insert">noOverlap_insert</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#noOverlap_movBack">noOverlap_movBack</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#noOverlap_movBack0">noOverlap_movBack0</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#noOverlap_movFront">noOverlap_movFront</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#noOverlap_nil">noOverlap_nil</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#noOverlap_Pop">noOverlap_Pop</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#noOverlap_pop">noOverlap_pop</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#noOverlap_right">noOverlap_right</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#noOverlap_swap">noOverlap_swap</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#noO_diff">noO_diff</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Allocproof_aux.html#noO_list_pnilnil">noO_list_pnilnil</a> [lemma, in <a href="backend.Allocproof_aux.html">backend.Allocproof_aux</a>]<br/>
-<a href="backend.Parallelmove.html#noRead">noRead</a> [definition, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#noRead_app">noRead_app</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#noRead_by_path">noRead_by_path</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Locations.html#norepet">norepet</a> [inductive, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#norepet_cons">norepet_cons</a> [constructor, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#norepet_nil">norepet_nil</a> [constructor, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Allocproof_aux.html#norepet_SD">norepet_SD</a> [lemma, in <a href="backend.Allocproof_aux.html">backend.Allocproof_aux</a>]<br/>
-<a href="lib.Integers.html#not">not</a> [definition, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Values.html#notbool">notbool</a> [definition, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Cmconstr.html#notbool">notbool</a> [definition, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="lib.Integers.html#notbool">notbool</a> [definition, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Cmconstr.html#notbool_base">notbool_base</a> [definition, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Values.html#notbool_idem2">notbool_idem2</a> [lemma, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Values.html#notbool_idem3">notbool_idem3</a> [lemma, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="lib.Integers.html#notbool_isfalse_istrue">notbool_isfalse_istrue</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#notbool_istrue_isfalse">notbool_istrue_isfalse</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Values.html#notbool_is_bool">notbool_is_bool</a> [lemma, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Values.html#notbool_negb_1">notbool_negb_1</a> [lemma, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Values.html#notbool_negb_2">notbool_negb_2</a> [lemma, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Values.html#notbool_xor">notbool_xor</a> [lemma, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Parallelmove.html#notemporary">notemporary</a> [definition, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Locations.html#notin">notin</a> [definition, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Parallelmove.html#notindst_nW">notindst_nW</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Values.html#notint">notint</a> [definition, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Cmconstr.html#notint">notint</a> [definition, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#notint_cases">notint_cases</a> [inductive, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#notint_case1">notint_case1</a> [constructor, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#notint_case2">notint_case2</a> [constructor, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#notint_case3">notint_case3</a> [constructor, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#notint_default">notint_default</a> [constructor, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#notint_match">notint_match</a> [definition, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Machabstr2mach.html#notin_callstack">notin_callstack</a> [inductive, in <a href="backend.Machabstr2mach.html">backend.Machabstr2mach</a>]<br/>
-<a href="backend.Machabstr2mach.html#notin_callstack_cons">notin_callstack_cons</a> [constructor, in <a href="backend.Machabstr2mach.html">backend.Machabstr2mach</a>]<br/>
-<a href="backend.Machabstr2mach.html#notin_callstack_nil">notin_callstack_nil</a> [constructor, in <a href="backend.Machabstr2mach.html">backend.Machabstr2mach</a>]<br/>
-<a href="backend.Locations.html#notin_disjoint">notin_disjoint</a> [lemma, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#notin_not_in">notin_not_in</a> [lemma, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Parallelmove.html#noTmp">noTmp</a> [definition, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#noTmpLast">noTmpLast</a> [definition, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#noTmpLast_lastnoTmp">noTmpLast_lastnoTmp</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#noTmpLast_Pop">noTmpLast_Pop</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#noTmpLast_pop">noTmpLast_pop</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#noTmpLast_popBack">noTmpLast_popBack</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#noTmpLast_push">noTmpLast_push</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#noTmpLast_tmpLast">noTmpLast_tmpLast</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#noTmpL_diff">noTmpL_diff</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#noTmp_app">noTmp_app</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#noTmp_append">noTmp_append</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#noTmP_noOverlap_aux">noTmP_noOverlap_aux</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#noTmp_noReadTmp">noTmp_noReadTmp</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#noTmp_noTmpLast">noTmp_noTmpLast</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#noTmp_pop">noTmp_pop</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Constprop.html#Novalue">Novalue</a> [constructor, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Parallelmove.html#noWrite">noWrite</a> [definition, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#noWrite_in">noWrite_in</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#noWrite_insert">noWrite_insert</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#noWrite_movFront">noWrite_movFront</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#noWrite_pop">noWrite_pop</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#noWrite_swap">noWrite_swap</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#noWrite_tmpLast">noWrite_tmpLast</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#no_overlap">no_overlap</a> [definition, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Locations.html#no_overlap">no_overlap</a> [definition, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Allocproof_aux.html#no_overlapD_inv">no_overlapD_inv</a> [lemma, in <a href="backend.Allocproof_aux.html">backend.Allocproof_aux</a>]<br/>
-<a href="backend.Allocproof_aux.html#no_overlapD_invf">no_overlapD_invf</a> [lemma, in <a href="backend.Allocproof_aux.html">backend.Allocproof_aux</a>]<br/>
-<a href="backend.Allocproof_aux.html#no_overlapD_invpp">no_overlapD_invpp</a> [lemma, in <a href="backend.Allocproof_aux.html">backend.Allocproof_aux</a>]<br/>
-<a href="backend.Allocproof_aux.html#no_overlapD_res">no_overlapD_res</a> [lemma, in <a href="backend.Allocproof_aux.html">backend.Allocproof_aux</a>]<br/>
-<a href="backend.Conventions.html#no_overlap_arguments">no_overlap_arguments</a> [lemma, in <a href="backend.Conventions.html">backend.Conventions</a>]<br/>
-<a href="backend.Parallelmove.html#no_overlap_list">no_overlap_list</a> [definition, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Allocproof_aux.html#no_overlap_list_pop">no_overlap_list_pop</a> [lemma, in <a href="backend.Allocproof_aux.html">backend.Allocproof_aux</a>]<br/>
-<a href="backend.Parallelmove.html#no_overlap_noOverlap">no_overlap_noOverlap</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Conventions.html#no_overlap_parameters">no_overlap_parameters</a> [lemma, in <a href="backend.Conventions.html">backend.Conventions</a>]<br/>
-<a href="backend.Parallelmove.html#no_overlap_state">no_overlap_state</a> [definition, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Allocproof_aux.html#no_overlap_stateD">no_overlap_stateD</a> [definition, in <a href="backend.Allocproof_aux.html">backend.Allocproof_aux</a>]<br/>
-<a href="backend.Allocproof_aux.html#no_overlap_temp">no_overlap_temp</a> [lemma, in <a href="backend.Allocproof_aux.html">backend.Allocproof_aux</a>]<br/>
-<a href="backend.Kildall.html#no_self_loop">no_self_loop</a> [lemma, in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Allocproof_aux.html#no_tmp13_state">no_tmp13_state</a> [definition, in <a href="backend.Allocproof_aux.html">backend.Allocproof_aux</a>]<br/>
-<a href="lib.Coqlib.html#nth_error_in">nth_error_in</a> [lemma, in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#nth_error_nil">nth_error_nil</a> [lemma, in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="backend.Mem.html#nullptr">nullptr</a> [definition, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.CSE.html#Numbering">Numbering</a> [module, in <a href="backend.CSE.html">backend.CSE</a>]<br/>
-<a href="backend.CSE.html#numbering">numbering</a> [inductive, in <a href="backend.CSE.html">backend.CSE</a>]<br/>
-<a href="backend.CSE.html#numbering_holds">numbering_holds</a> [definition, in <a href="backend.CSE.html">backend.CSE</a>]<br/>
-<a href="backend.CSEproof.html#numbering_holds_exten">numbering_holds_exten</a> [lemma, in <a href="backend.CSEproof.html">backend.CSEproof</a>]<br/>
-<a href="backend.CSE.html#numbering_satisfiable">numbering_satisfiable</a> [definition, in <a href="backend.CSE.html">backend.CSE</a>]<br/>
-<a href="backend.Kildall.html#num_iterations">num_iterations</a> [definition, in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<br/><br/><a name="global_O"></a><h2>O </h2>
-<a href="backend.Op.html#Oabsf">Oabsf</a> [constructor, in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Csharpminor.html#Oabsf">Oabsf</a> [constructor, in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Csharpminor.html#Oadd">Oadd</a> [constructor, in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Op.html#Oadd">Oadd</a> [constructor, in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Csharpminor.html#Oaddf">Oaddf</a> [constructor, in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Op.html#Oaddf">Oaddf</a> [constructor, in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Op.html#Oaddimm">Oaddimm</a> [constructor, in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Op.html#Oaddrstack">Oaddrstack</a> [constructor, in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Op.html#Oaddrsymbol">Oaddrsymbol</a> [constructor, in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Op.html#Oand">Oand</a> [constructor, in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Csharpminor.html#Oand">Oand</a> [constructor, in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Op.html#Oandimm">Oandimm</a> [constructor, in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Csharpminor.html#Ocast16signed">Ocast16signed</a> [constructor, in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Op.html#Ocast16signed">Ocast16signed</a> [constructor, in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Csharpminor.html#Ocast16unsigned">Ocast16unsigned</a> [constructor, in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Csharpminor.html#Ocast8signed">Ocast8signed</a> [constructor, in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Op.html#Ocast8signed">Ocast8signed</a> [constructor, in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Csharpminor.html#Ocast8unsigned">Ocast8unsigned</a> [constructor, in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Op.html#Ocmp">Ocmp</a> [constructor, in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Csharpminor.html#Ocmp">Ocmp</a> [constructor, in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Csharpminor.html#Ocmpf">Ocmpf</a> [constructor, in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Csharpminor.html#Ocmpu">Ocmpu</a> [constructor, in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Op.html#Odiv">Odiv</a> [constructor, in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Csharpminor.html#Odiv">Odiv</a> [constructor, in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Op.html#Odivf">Odivf</a> [constructor, in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Csharpminor.html#Odivf">Odivf</a> [constructor, in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Csharpminor.html#Odivu">Odivu</a> [constructor, in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Op.html#Odivu">Odivu</a> [constructor, in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Stacking.html#offset_of_index">offset_of_index</a> [definition, in <a href="backend.Stacking.html">backend.Stacking</a>]<br/>
-<a href="backend.Stackingproof.html#offset_of_index_disj">offset_of_index_disj</a> [lemma, in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="backend.Stackingproof.html#offset_of_index_no_overflow">offset_of_index_no_overflow</a> [lemma, in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="backend.Stackingproof.html#offset_of_index_valid">offset_of_index_valid</a> [lemma, in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="backend.Op.html#offset_sp">offset_sp</a> [definition, in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Op.html#Ofloatconst">Ofloatconst</a> [constructor, in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Csharpminor.html#Ofloatconst">Ofloatconst</a> [constructor, in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Op.html#Ofloatofint">Ofloatofint</a> [constructor, in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Csharpminor.html#Ofloatofint">Ofloatofint</a> [constructor, in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Csharpminor.html#Ofloatofintu">Ofloatofintu</a> [constructor, in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Op.html#Ofloatofintu">Ofloatofintu</a> [constructor, in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Values.html#of_bool">of_bool</a> [definition, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Values.html#of_bool_is_bool">of_bool_is_bool</a> [lemma, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Csharpminor.html#Ointconst">Ointconst</a> [constructor, in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Op.html#Ointconst">Ointconst</a> [constructor, in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Csharpminor.html#Ointoffloat">Ointoffloat</a> [constructor, in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Op.html#Ointoffloat">Ointoffloat</a> [constructor, in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.RTLgen.html#OK">OK</a> [constructor, in <a href="backend.RTLgen.html">backend.RTLgen</a>]<br/>
-<a href="backend.PPC.html#OK">OK</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.Csharpminor.html#Omod">Omod</a> [constructor, in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Csharpminor.html#Omodu">Omodu</a> [constructor, in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Op.html#Omove">Omove</a> [constructor, in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Csharpminor.html#Omul">Omul</a> [constructor, in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Op.html#Omul">Omul</a> [constructor, in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Op.html#Omuladdf">Omuladdf</a> [constructor, in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Op.html#Omulf">Omulf</a> [constructor, in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Csharpminor.html#Omulf">Omulf</a> [constructor, in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Op.html#Omulimm">Omulimm</a> [constructor, in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Op.html#Omulsubf">Omulsubf</a> [constructor, in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Op.html#Onand">Onand</a> [constructor, in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="lib.Integers.html#one">one</a> [definition, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Floats.html#one">one</a> [axiom, in <a href="lib.Floats.html">lib.Floats</a>]<br/>
-<a href="backend.Csharpminor.html#Onegf">Onegf</a> [constructor, in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Op.html#Onegf">Onegf</a> [constructor, in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="lib.Integers.html#one_bits">one_bits</a> [definition, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#one_bits_decomp">one_bits_decomp</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#one_bits_range">one_bits_range</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#one_not_zero">one_not_zero</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Op.html#Onor">Onor</a> [constructor, in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Csharpminor.html#Onotint">Onotint</a> [constructor, in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Op.html#Onxor">Onxor</a> [constructor, in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Op.html#Oor">Oor</a> [constructor, in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Csharpminor.html#Oor">Oor</a> [constructor, in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Op.html#Oorimm">Oorimm</a> [constructor, in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.CSE.html#Op">Op</a> [constructor, in <a href="backend.CSE.html">backend.CSE</a>]<br/>
-<a href="backend.Op.html">Op</a> [library]<br/>
-<a href="backend.Csharpminor.html#operation">operation</a> [inductive, in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Op.html#operation">operation</a> [inductive, in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.RTLtyping.html#option_fold2">option_fold2</a> [definition, in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="lib.Coqlib.html#option_map">option_map</a> [definition, in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.union_find.html#option_sum">option_sum</a> [lemma, in <a href="lib.union_find.html">lib.union_find</a>]<br/>
-<a href="backend.Constprop.html#op_strength_reduction">op_strength_reduction</a> [definition, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#op_strength_reduction_cases">op_strength_reduction_cases</a> [inductive, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#op_strength_reduction_case1">op_strength_reduction_case1</a> [constructor, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#op_strength_reduction_case10">op_strength_reduction_case10</a> [constructor, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#op_strength_reduction_case11">op_strength_reduction_case11</a> [constructor, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#op_strength_reduction_case12">op_strength_reduction_case12</a> [constructor, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#op_strength_reduction_case2">op_strength_reduction_case2</a> [constructor, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#op_strength_reduction_case3">op_strength_reduction_case3</a> [constructor, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#op_strength_reduction_case4">op_strength_reduction_case4</a> [constructor, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#op_strength_reduction_case5">op_strength_reduction_case5</a> [constructor, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#op_strength_reduction_case6">op_strength_reduction_case6</a> [constructor, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#op_strength_reduction_case7">op_strength_reduction_case7</a> [constructor, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#op_strength_reduction_case8">op_strength_reduction_case8</a> [constructor, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#op_strength_reduction_case9">op_strength_reduction_case9</a> [constructor, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constpropproof.html#op_strength_reduction_correct">op_strength_reduction_correct</a> [lemma, in <a href="backend.Constpropproof.html">backend.Constpropproof</a>]<br/>
-<a href="backend.Constprop.html#op_strength_reduction_default">op_strength_reduction_default</a> [constructor, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#op_strength_reduction_match">op_strength_reduction_match</a> [definition, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="lib.Integers.html#or">or</a> [definition, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Values.html#or">or</a> [definition, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Cmconstr.html#or">or</a> [definition, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="lib.Ordered.html">Ordered</a> [library]<br/>
-<a href="lib.Ordered.html#OrderedIndexed">OrderedIndexed</a> [module, in <a href="lib.Ordered.html">lib.Ordered</a>]<br/>
-<a href="backend.InterfGraph.html#OrderedMreg">OrderedMreg</a> [module, in <a href="backend.InterfGraph.html">backend.InterfGraph</a>]<br/>
-<a href="lib.Ordered.html#OrderedPair">OrderedPair</a> [module, in <a href="lib.Ordered.html">lib.Ordered</a>]<br/>
-<a href="lib.Ordered.html#OrderedPositive">OrderedPositive</a> [module, in <a href="lib.Ordered.html">lib.Ordered</a>]<br/>
-<a href="backend.InterfGraph.html#OrderedReg">OrderedReg</a> [module, in <a href="backend.InterfGraph.html">backend.InterfGraph</a>]<br/>
-<a href="backend.InterfGraph.html#OrderedRegMreg">OrderedRegMreg</a> [module, in <a href="backend.InterfGraph.html">backend.InterfGraph</a>]<br/>
-<a href="backend.InterfGraph.html#OrderedRegReg">OrderedRegReg</a> [module, in <a href="backend.InterfGraph.html">backend.InterfGraph</a>]<br/>
-<a href="backend.InterfGraph.html#ordered_pair">ordered_pair</a> [definition, in <a href="backend.InterfGraph.html">backend.InterfGraph</a>]<br/>
-<a href="backend.InterfGraph.html#ordered_pair_charact">ordered_pair_charact</a> [lemma, in <a href="backend.InterfGraph.html">backend.InterfGraph</a>]<br/>
-<a href="backend.InterfGraph.html#ordered_pair_sym">ordered_pair_sym</a> [lemma, in <a href="backend.InterfGraph.html">backend.InterfGraph</a>]<br/>
-<a href="backend.Kildall.html#ORDERED_TYPE_WITH_TOP">ORDERED_TYPE_WITH_TOP</a> [module, in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.PPCgen.html#orimm">orimm</a> [definition, in <a href="backend.PPCgen.html">backend.PPCgen</a>]<br/>
-<a href="backend.PPCgenproof1.html#orimm_correct">orimm_correct</a> [lemma, in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.Op.html#Orolm">Orolm</a> [constructor, in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="lib.Integers.html#or_assoc">or_assoc</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Values.html#or_assoc">or_assoc</a> [lemma, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Cmconstr.html#or_cases">or_cases</a> [inductive, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#or_case1">or_case1</a> [constructor, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="lib.Integers.html#or_commut">or_commut</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Values.html#or_commut">or_commut</a> [lemma, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Cmconstr.html#or_default">or_default</a> [constructor, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="lib.Integers.html#or_idem">or_idem</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Cmconstr.html#or_match">or_match</a> [definition, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="lib.Integers.html#or_mone">or_mone</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Values.html#or_of_bool">or_of_bool</a> [lemma, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="lib.Integers.html#or_rolm">or_rolm</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Values.html#or_rolm">or_rolm</a> [lemma, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="lib.Integers.html#or_zero">or_zero</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Csharpminor.html#Oshl">Oshl</a> [constructor, in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Op.html#Oshl">Oshl</a> [constructor, in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Op.html#Oshr">Oshr</a> [constructor, in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Csharpminor.html#Oshr">Oshr</a> [constructor, in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Op.html#Oshrimm">Oshrimm</a> [constructor, in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Op.html#Oshru">Oshru</a> [constructor, in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Csharpminor.html#Oshru">Oshru</a> [constructor, in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Op.html#Oshrximm">Oshrximm</a> [constructor, in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Op.html#Osingleoffloat">Osingleoffloat</a> [constructor, in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Csharpminor.html#Osingleoffloat">Osingleoffloat</a> [constructor, in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Csharpminor.html#Osub">Osub</a> [constructor, in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Op.html#Osub">Osub</a> [constructor, in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Csharpminor.html#Osubf">Osubf</a> [constructor, in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Op.html#Osubf">Osubf</a> [constructor, in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Op.html#Osubimm">Osubimm</a> [constructor, in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Op.html#Oundef">Oundef</a> [constructor, in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Cminor.html#outcome">outcome</a> [inductive, in <a href="backend.Cminor.html">backend.Cminor</a>]<br/>
-<a href="backend.LTL.html#outcome">outcome</a> [inductive, in <a href="backend.LTL.html">backend.LTL</a>]<br/>
-<a href="backend.PPC.html#outcome">outcome</a> [inductive, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.Csharpminor.html#outcome">outcome</a> [inductive, in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Csharpminor.html#outcome_block">outcome_block</a> [definition, in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Cminor.html#outcome_block">outcome_block</a> [definition, in <a href="backend.Cminor.html">backend.Cminor</a>]<br/>
-<a href="backend.Cminorgenproof.html#outcome_inject">outcome_inject</a> [inductive, in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.RTLgenproof.html#outcome_node">outcome_node</a> [definition, in <a href="backend.RTLgenproof.html">backend.RTLgenproof</a>]<br/>
-<a href="backend.Cminor.html#outcome_result_value">outcome_result_value</a> [definition, in <a href="backend.Cminor.html">backend.Cminor</a>]<br/>
-<a href="backend.Csharpminor.html#outcome_result_value">outcome_result_value</a> [definition, in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Locations.html#Outgoing">Outgoing</a> [constructor, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Lineartyping.html#outgoing_slot">outgoing_slot</a> [definition, in <a href="backend.Lineartyping.html">backend.Lineartyping</a>]<br/>
-<a href="backend.Linearizetyping.html#outgoing_slot_bound">outgoing_slot_bound</a> [lemma, in <a href="backend.Linearizetyping.html">backend.Linearizetyping</a>]<br/>
-<a href="backend.Lineartyping.html#outgoing_space">outgoing_space</a> [definition, in <a href="backend.Lineartyping.html">backend.Lineartyping</a>]<br/>
-<a href="backend.Csharpminor.html#Out_exit">Out_exit</a> [constructor, in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Cminor.html#Out_exit">Out_exit</a> [constructor, in <a href="backend.Cminor.html">backend.Cminor</a>]<br/>
-<a href="backend.Cminor.html#Out_normal">Out_normal</a> [constructor, in <a href="backend.Cminor.html">backend.Cminor</a>]<br/>
-<a href="backend.Csharpminor.html#Out_normal">Out_normal</a> [constructor, in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Cminor.html#Out_return">Out_return</a> [constructor, in <a href="backend.Cminor.html">backend.Cminor</a>]<br/>
-<a href="backend.Csharpminor.html#Out_return">Out_return</a> [constructor, in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Locations.html#overlap">overlap</a> [definition, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#overlap_aux">overlap_aux</a> [definition, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#overlap_aux_false_1">overlap_aux_false_1</a> [lemma, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#overlap_aux_true_1">overlap_aux_true_1</a> [lemma, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#overlap_aux_true_2">overlap_aux_true_2</a> [lemma, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#overlap_not_diff">overlap_not_diff</a> [lemma, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Op.html#Oxor">Oxor</a> [constructor, in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Csharpminor.html#Oxor">Oxor</a> [constructor, in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Op.html#Oxorimm">Oxorimm</a> [constructor, in <a href="backend.Op.html">backend.Op</a>]<br/>
-<br/><br/><a name="global_P"></a><h2>P </h2>
-<a href="backend.PPC.html#Padd">Padd</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Paddi">Paddi</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Paddis">Paddis</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Paddze">Paddze</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pallocframe">Pallocframe</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pandc">Pandc</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pandis_">Pandis_</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pandi_">Pandi_</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pand_">Pand_</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.Parallelmove.html">Parallelmove</a> [library]<br/>
-<a href="backend.Allocation.html#parallel_move">parallel_move</a> [definition, in <a href="backend.Allocation.html">backend.Allocation</a>]<br/>
-<a href="backend.Allocproof.html#parallel_move_correct">parallel_move_correct</a> [lemma, in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.Allocproof_aux.html#parallel_move_correctX">parallel_move_correctX</a> [lemma, in <a href="backend.Allocproof_aux.html">backend.Allocproof_aux</a>]<br/>
-<a href="backend.Allocproof_aux.html#parallel_move_correct'">parallel_move_correct'</a> [lemma, in <a href="backend.Allocproof_aux.html">backend.Allocproof_aux</a>]<br/>
-<a href="backend.Allocation.html#parallel_move_order">parallel_move_order</a> [definition, in <a href="backend.Allocation.html">backend.Allocation</a>]<br/>
-<a href="backend.Conventions.html#parameter_of_argument">parameter_of_argument</a> [definition, in <a href="backend.Conventions.html">backend.Conventions</a>]<br/>
-<a href="backend.Parallelmove.html#path">path</a> [definition, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#path_pop">path_pop</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#path_tmpLast">path_tmpLast</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.PPC.html#Pb">Pb</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pbctr">Pbctr</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pbctrl">Pbctrl</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pbf">Pbf</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pbl">Pbl</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pblr">Pblr</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pbt">Pbt</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#PC">PC</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pcmplw">Pcmplw</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pcmplwi">Pcmplwi</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pcmpw">Pcmpw</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pcmpwi">Pcmpwi</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pcror">Pcror</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pdivw">Pdivw</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pdivwu">Pdivwu</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="lib.Coqlib.html#peq">peq</a> [definition, in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="backend.PPC.html#Peqv">Peqv</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="lib.Coqlib.html#peq_false">peq_false</a> [lemma, in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#peq_true">peq_true</a> [lemma, in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="backend.Parallelmove.html#pexec">pexec</a> [definition, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#pexec_add">pexec_add</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#pexec_correct">pexec_correct</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#pexec_mov">pexec_mov</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#pexec_movBack">pexec_movBack</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#pexec_movFront">pexec_movFront</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#pexec_nop">pexec_nop</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#pexec_push">pexec_push</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#pexec_swap">pexec_swap</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#pexec_update">pexec_update</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.PPC.html#Pextsb">Pextsb</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pextsh">Pextsh</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pfabs">Pfabs</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pfadd">Pfadd</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pfcmpu">Pfcmpu</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pfcti">Pfcti</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pfdiv">Pfdiv</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pfmadd">Pfmadd</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pfmr">Pfmr</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pfmsub">Pfmsub</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pfmul">Pfmul</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pfneg">Pfneg</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pfreeframe">Pfreeframe</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pfrsp">Pfrsp</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pfsub">Pfsub</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pfundef">Pfundef</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pictf">Pictf</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Piuctf">Piuctf</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Piundef">Piundef</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Plabel">Plabel</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Plbz">Plbz</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Plbzx">Plbzx</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="lib.Coqlib.html#Ple">Ple</a> [definition, in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#Ple_refl">Ple_refl</a> [lemma, in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#Ple_succ">Ple_succ</a> [lemma, in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#Ple_trans">Ple_trans</a> [lemma, in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="backend.PPC.html#Plfd">Plfd</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Plfdx">Plfdx</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Plfi">Plfi</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Plfs">Plfs</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Plfsx">Plfsx</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Plha">Plha</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Plhax">Plhax</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Plhz">Plhz</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Plhzx">Plhzx</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="lib.Coqlib.html#Plt">Plt</a> [definition, in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#plt">plt</a> [definition, in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#Plt_ne">Plt_ne</a> [lemma, in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#Plt_Ple">Plt_Ple</a> [lemma, in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#Plt_Ple_trans">Plt_Ple_trans</a> [lemma, in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#Plt_strict">Plt_strict</a> [lemma, in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#Plt_succ">Plt_succ</a> [lemma, in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#Plt_succ_inv">Plt_succ_inv</a> [lemma, in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#Plt_trans">Plt_trans</a> [lemma, in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#Plt_trans_succ">Plt_trans_succ</a> [lemma, in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#Plt_wf">Plt_wf</a> [lemma, in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="backend.PPC.html#Plwz">Plwz</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Plwzx">Plwzx</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="lib.Maps.html#PMap">PMap</a> [module, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="backend.PPC.html#Pmfcrbit">Pmfcrbit</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pmflr">Pmflr</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.Parallelmove.html#Pmov">Pmov</a> [definition, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#Pmov_equation">Pmov_equation</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.PPC.html#Pmr">Pmr</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pmtctr">Pmtctr</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pmtlr">Pmtlr</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pmulli">Pmulli</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pmullw">Pmullw</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pnand">Pnand</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pnor">Pnor</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Por">Por</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Porc">Porc</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pori">Pori</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Poris">Poris</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="lib.Coqlib.html#positive_Peano_ind">positive_Peano_ind</a> [lemma, in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#positive_rec">positive_rec</a> [definition, in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#positive_rec_base">positive_rec_base</a> [lemma, in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#positive_rec_succ">positive_rec_succ</a> [lemma, in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Integers.html#powerserie">powerserie</a> [definition, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.PPC.html">PPC</a> [library]<br/>
-<a href="backend.PPCgen.html">PPCgen</a> [library]<br/>
-<a href="backend.PPCgenproof.html">PPCgenproof</a> [library]<br/>
-<a href="backend.PPCgenproof1.html">PPCgenproof1</a> [library]<br/>
-<a href="lib.Coqlib.html#Ppred_Plt">Ppred_Plt</a> [lemma, in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="backend.Kildall.html#predecessors">predecessors</a> [definition, in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Kildall.html#predecessors_correct">predecessors_correct</a> [lemma, in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.PPC.html#preg">preg</a> [inductive, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#PregEq">PregEq</a> [module, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pregmap">Pregmap</a> [module, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#preg_eq">preg_eq</a> [lemma, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPCgenproof1.html#preg_of">preg_of</a> [definition, in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.PPCgenproof1.html#preg_of_injective">preg_of_injective</a> [lemma, in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.PPCgenproof1.html#preg_of_is_data_reg">preg_of_is_data_reg</a> [lemma, in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.PPCgenproof1.html#preg_of_not">preg_of_not</a> [lemma, in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.PPCgenproof1.html#preg_of_not_GPR1">preg_of_not_GPR1</a> [lemma, in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.PPCgenproof1.html#preg_val">preg_val</a> [lemma, in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.PPC.html#Prlwinm">Prlwinm</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.LTL.html#program">program</a> [definition, in <a href="backend.LTL.html">backend.LTL</a>]<br/>
-<a href="backend.Cminor.html#program">program</a> [definition, in <a href="backend.Cminor.html">backend.Cminor</a>]<br/>
-<a href="backend.Linear.html#program">program</a> [definition, in <a href="backend.Linear.html">backend.Linear</a>]<br/>
-<a href="backend.AST.html#program">program</a> [inductive, in <a href="backend.AST.html">backend.AST</a>]<br/>
-<a href="backend.RTL.html#program">program</a> [definition, in <a href="backend.RTL.html">backend.RTL</a>]<br/>
-<a href="backend.Csharpminor.html#program">program</a> [definition, in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.PPC.html#program">program</a> [definition, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.Mach.html#program">program</a> [definition, in <a href="backend.Mach.html">backend.Mach</a>]<br/>
-<a href="backend.Tunnelingtyping.html#program_typing_preserved">program_typing_preserved</a> [lemma, in <a href="backend.Tunnelingtyping.html">backend.Tunnelingtyping</a>]<br/>
-<a href="backend.Linearizetyping.html#program_typing_preserved">program_typing_preserved</a> [lemma, in <a href="backend.Linearizetyping.html">backend.Linearizetyping</a>]<br/>
-<a href="backend.Alloctyping.html#program_typing_preserved">program_typing_preserved</a> [lemma, in <a href="backend.Alloctyping.html">backend.Alloctyping</a>]<br/>
-<a href="backend.Stackingtyping.html#program_typing_preserved">program_typing_preserved</a> [lemma, in <a href="backend.Stackingtyping.html">backend.Stackingtyping</a>]<br/>
-<a href="backend.Globalenvs.html#prog_funct_transf_OK">prog_funct_transf_OK</a> [lemma, in <a href="backend.Globalenvs.html">backend.Globalenvs</a>]<br/>
-<a href="lib.Coqlib.html#proof_irrelevance">proof_irrelevance</a> [axiom, in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="backend.Kildall.html#propagate_succ">propagate_succ</a> [definition, in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Kildall.html#propagate_successors">propagate_successors</a> [definition, in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Kildall.html#propagate_successors_charact1">propagate_successors_charact1</a> [lemma, in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Kildall.html#propagate_successors_charact2">propagate_successors_charact2</a> [lemma, in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Kildall.html#propagate_successors_invariant">propagate_successors_invariant</a> [lemma, in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Kildall.html#propagate_successors_P">propagate_successors_P</a> [lemma, in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Kildall.html#propagate_succ_charact">propagate_succ_charact</a> [lemma, in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Kildall.html#propagate_succ_incr">propagate_succ_incr</a> [lemma, in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Kildall.html#propagate_succ_incr_worklist">propagate_succ_incr_worklist</a> [lemma, in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Kildall.html#propagate_succ_list">propagate_succ_list</a> [definition, in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Kildall.html#propagate_succ_list_charact">propagate_succ_list_charact</a> [lemma, in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Kildall.html#propagate_succ_list_incr">propagate_succ_list_incr</a> [lemma, in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Kildall.html#propagate_succ_list_incr_worklist">propagate_succ_list_incr_worklist</a> [lemma, in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Kildall.html#propagate_succ_list_records_changes">propagate_succ_list_records_changes</a> [lemma, in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Kildall.html#propagate_succ_records_changes">propagate_succ_records_changes</a> [lemma, in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.PPC.html#Pslw">Pslw</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Psraw">Psraw</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Psrawi">Psrawi</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Psrw">Psrw</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.Kildall.html#Pstate">Pstate</a> [definition, in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.PPC.html#Pstb">Pstb</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pstbx">Pstbx</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pstfd">Pstfd</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pstfdx">Pstfdx</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pstfs">Pstfs</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pstfsx">Pstfsx</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Psth">Psth</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Psthx">Psthx</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pstw">Pstw</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pstwx">Pstwx</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Psubfc">Psubfc</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Psubfic">Psubfic</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="lib.Maps.html#PTree">PTree</a> [module, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="backend.PPC.html#Pxor">Pxor</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pxori">Pxori</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pxoris">Pxoris</a> [constructor, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.Allocproof_aux.html#p_move">p_move</a> [definition, in <a href="backend.Allocproof_aux.html">backend.Allocproof_aux</a>]<br/>
-<a href="backend.Parallelmove.html#P_move">P_move</a> [definition, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<br/><br/><a name="global_R"></a><h2>R </h2>
-<a href="backend.Locations.html#R">R</a> [constructor, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Coloring.html#R">R</a> [definition, in <a href="backend.Coloring.html">backend.Coloring</a>]<br/>
-<a href="backend.Linearize.html#reachable">reachable</a> [definition, in <a href="backend.Linearize.html">backend.Linearize</a>]<br/>
-<a href="backend.Linearize.html#reachable_aux">reachable_aux</a> [definition, in <a href="backend.Linearize.html">backend.Linearize</a>]<br/>
-<a href="backend.Linearizeproof.html#reachable_correct_1">reachable_correct_1</a> [lemma, in <a href="backend.Linearizeproof.html">backend.Linearizeproof</a>]<br/>
-<a href="backend.Linearizeproof.html#reachable_correct_2">reachable_correct_2</a> [lemma, in <a href="backend.Linearizeproof.html">backend.Linearizeproof</a>]<br/>
-<a href="backend.Linearizeproof.html#reachable_entrypoint">reachable_entrypoint</a> [lemma, in <a href="backend.Linearizeproof.html">backend.Linearizeproof</a>]<br/>
-<a href="backend.Linearizeproof.html#reachable_successors">reachable_successors</a> [lemma, in <a href="backend.Linearizeproof.html">backend.Linearizeproof</a>]<br/>
-<a href="backend.Parallelmove.html#rebuild_l">rebuild_l</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.CSE.html#refl_ge">refl_ge</a> [lemma, in <a href="backend.CSE.html">backend.CSE</a>]<br/>
-<a href="backend.Registers.html#Reg">Reg</a> [module, in <a href="backend.Registers.html">backend.Registers</a>]<br/>
-<a href="backend.Registers.html#reg">reg</a> [definition, in <a href="backend.Registers.html">backend.Registers</a>]<br/>
-<a href="backend.Parallelmove.html#Reg">Reg</a> [definition, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Coloring.html#regalloc">regalloc</a> [definition, in <a href="backend.Coloring.html">backend.Coloring</a>]<br/>
-<a href="backend.Coloringproof.html#regalloc_acceptable">regalloc_acceptable</a> [lemma, in <a href="backend.Coloringproof.html">backend.Coloringproof</a>]<br/>
-<a href="backend.Coloringproof.html#regalloc_correct_1">regalloc_correct_1</a> [lemma, in <a href="backend.Coloringproof.html">backend.Coloringproof</a>]<br/>
-<a href="backend.Coloringproof.html#regalloc_correct_2">regalloc_correct_2</a> [lemma, in <a href="backend.Coloringproof.html">backend.Coloringproof</a>]<br/>
-<a href="backend.Coloringproof.html#regalloc_correct_3">regalloc_correct_3</a> [lemma, in <a href="backend.Coloringproof.html">backend.Coloringproof</a>]<br/>
-<a href="backend.Allocproof.html#regalloc_disj_temporaries">regalloc_disj_temporaries</a> [lemma, in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.Allocproof.html#regalloc_norepet_norepet">regalloc_norepet_norepet</a> [lemma, in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.Allocproof.html#regalloc_noteq_diff">regalloc_noteq_diff</a> [lemma, in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.Allocproof.html#regalloc_notin_notin">regalloc_notin_notin</a> [lemma, in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.Allocproof.html#regalloc_not_temporary">regalloc_not_temporary</a> [lemma, in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.Coloringproof.html#regalloc_ok">regalloc_ok</a> [lemma, in <a href="backend.Coloringproof.html">backend.Coloringproof</a>]<br/>
-<a href="backend.Coloringproof.html#regalloc_preserves_types">regalloc_preserves_types</a> [lemma, in <a href="backend.Coloringproof.html">backend.Coloringproof</a>]<br/>
-<a href="backend.RTLtyping.html#regenv">regenv</a> [definition, in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.Mach.html#RegEq">RegEq</a> [module, in <a href="backend.Mach.html">backend.Mach</a>]<br/>
-<a href="backend.Registers.html">Registers</a> [library]<br/>
-<a href="backend.Conventions.html#register_classification">register_classification</a> [lemma, in <a href="backend.Conventions.html">backend.Conventions</a>]<br/>
-<a href="backend.LTL.html#reglist">reglist</a> [definition, in <a href="backend.LTL.html">backend.LTL</a>]<br/>
-<a href="backend.Mach.html#Regmap">Regmap</a> [module, in <a href="backend.Mach.html">backend.Mach</a>]<br/>
-<a href="backend.Registers.html#Regmap">Regmap</a> [module, in <a href="backend.Registers.html">backend.Registers</a>]<br/>
-<a href="backend.Registers.html#regmap_optget">regmap_optget</a> [definition, in <a href="backend.Registers.html">backend.Registers</a>]<br/>
-<a href="backend.Registers.html#regmap_optset">regmap_optset</a> [definition, in <a href="backend.Registers.html">backend.Registers</a>]<br/>
-<a href="backend.Coloringproof.html#regsalloc_acceptable">regsalloc_acceptable</a> [lemma, in <a href="backend.Coloringproof.html">backend.Coloringproof</a>]<br/>
-<a href="backend.Mach.html#regset">regset</a> [definition, in <a href="backend.Mach.html">backend.Mach</a>]<br/>
-<a href="backend.RTL.html#regset">regset</a> [definition, in <a href="backend.RTL.html">backend.RTL</a>]<br/>
-<a href="backend.PPC.html#regset">regset</a> [definition, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.Registers.html#Regset">Regset</a> [module, in <a href="backend.Registers.html">backend.Registers</a>]<br/>
-<a href="backend.Allocation.html#regs_for">regs_for</a> [definition, in <a href="backend.Allocation.html">backend.Allocation</a>]<br/>
-<a href="backend.Allocation.html#regs_for_rec">regs_for_rec</a> [definition, in <a href="backend.Allocation.html">backend.Allocation</a>]<br/>
-<a href="backend.Constpropproof.html#regs_match_approx">regs_match_approx</a> [definition, in <a href="backend.Constpropproof.html">backend.Constpropproof</a>]<br/>
-<a href="backend.Constpropproof.html#regs_match_approx_increasing">regs_match_approx_increasing</a> [lemma, in <a href="backend.Constpropproof.html">backend.Constpropproof</a>]<br/>
-<a href="backend.Constpropproof.html#regs_match_approx_update">regs_match_approx_update</a> [lemma, in <a href="backend.Constpropproof.html">backend.Constpropproof</a>]<br/>
-<a href="backend.Lineartyping.html#regs_of_instr">regs_of_instr</a> [definition, in <a href="backend.Lineartyping.html">backend.Lineartyping</a>]<br/>
-<a href="backend.Allocation.html#reg_for">reg_for</a> [definition, in <a href="backend.Allocation.html">backend.Allocation</a>]<br/>
-<a href="backend.Allocproof.html#reg_for_spec">reg_for_spec</a> [lemma, in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.RTLgenproof1.html#reg_fresh">reg_fresh</a> [definition, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#reg_fresh_decr">reg_fresh_decr</a> [lemma, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#reg_in_map">reg_in_map</a> [definition, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#reg_in_map_valid">reg_in_map_valid</a> [lemma, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.Allocation.html#reg_list_dead">reg_list_dead</a> [definition, in <a href="backend.Allocation.html">backend.Allocation</a>]<br/>
-<a href="backend.Allocation.html#reg_list_live">reg_list_live</a> [definition, in <a href="backend.Allocation.html">backend.Allocation</a>]<br/>
-<a href="backend.PPC.html#reg_of_crbit">reg_of_crbit</a> [definition, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.Allocation.html#reg_option_live">reg_option_live</a> [definition, in <a href="backend.Allocation.html">backend.Allocation</a>]<br/>
-<a href="backend.Allocation.html#reg_sum_live">reg_sum_live</a> [definition, in <a href="backend.Allocation.html">backend.Allocation</a>]<br/>
-<a href="backend.RTLgenproof1.html#reg_valid">reg_valid</a> [definition, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#reg_valid_incr">reg_valid_incr</a> [lemma, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.CSE.html#reg_valnum">reg_valnum</a> [definition, in <a href="backend.CSE.html">backend.CSE</a>]<br/>
-<a href="backend.CSEproof.html#reg_valnum_correct">reg_valnum_correct</a> [lemma, in <a href="backend.CSEproof.html">backend.CSEproof</a>]<br/>
-<a href="lib.Sets.html#remove">remove</a> [definition, in <a href="lib.Sets.html">lib.Sets</a>]<br/>
-<a href="lib.Maps.html#remove">remove</a> [definition, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Inclusion.html#remove_all_leaves">remove_all_leaves</a> [definition, in <a href="lib.Inclusion.html">lib.Inclusion</a>]<br/>
-<a href="lib.Inclusion.html#remove_all_leaves_sound">remove_all_leaves_sound</a> [lemma, in <a href="lib.Inclusion.html">lib.Inclusion</a>]<br/>
-<a href="backend.RTLtyping.html#repet">repet</a> [definition, in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.RTLtyping.html#repet_correct">repet_correct</a> [lemma, in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.Parallelmove.html#replace_last_id">replace_last_id</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#replace_last_s">replace_last_s</a> [definition, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="lib.union_find.html#repr">repr</a> [definition, in <a href="lib.union_find.html">lib.union_find</a>]<br/>
-<a href="lib.Integers.html#repr">repr</a> [definition, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.union_find.html#repr_aux">repr_aux</a> [definition, in <a href="lib.union_find.html">lib.union_find</a>]<br/>
-<a href="lib.union_find.html#repr_aux_canon">repr_aux_canon</a> [lemma, in <a href="lib.union_find.html">lib.union_find</a>]<br/>
-<a href="lib.union_find.html#repr_aux_none">repr_aux_none</a> [lemma, in <a href="lib.union_find.html">lib.union_find</a>]<br/>
-<a href="lib.union_find.html#repr_aux_some">repr_aux_some</a> [lemma, in <a href="lib.union_find.html">lib.union_find</a>]<br/>
-<a href="lib.union_find.html#repr_empty">repr_empty</a> [lemma, in <a href="lib.union_find.html">lib.union_find</a>]<br/>
-<a href="lib.union_find.html#repr_order">repr_order</a> [definition, in <a href="lib.union_find.html">lib.union_find</a>]<br/>
-<a href="lib.union_find.html#repr_rec">repr_rec</a> [definition, in <a href="lib.union_find.html">lib.union_find</a>]<br/>
-<a href="lib.union_find.html#repr_rec_ext">repr_rec_ext</a> [lemma, in <a href="lib.union_find.html">lib.union_find</a>]<br/>
-<a href="lib.union_find.html#repr_repr">repr_repr</a> [lemma, in <a href="lib.union_find.html">lib.union_find</a>]<br/>
-<a href="lib.Integers.html#repr_signed">repr_signed</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#repr_unsigned">repr_unsigned</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.RTLgen.html#res">res</a> [inductive, in <a href="backend.RTLgen.html">backend.RTLgen</a>]<br/>
-<a href="backend.RTLgen.html#reserve_instr">reserve_instr</a> [definition, in <a href="backend.RTLgen.html">backend.RTLgen</a>]<br/>
-<a href="backend.RTLgenproof1.html#reserve_instr_incr">reserve_instr_incr</a> [lemma, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgen.html#reserve_instr_wf">reserve_instr_wf</a> [lemma, in <a href="backend.RTLgen.html">backend.RTLgen</a>]<br/>
-<a href="backend.Stacking.html#restore_callee_save">restore_callee_save</a> [definition, in <a href="backend.Stacking.html">backend.Stacking</a>]<br/>
-<a href="backend.Stackingproof.html#restore_callee_save_correct">restore_callee_save_correct</a> [lemma, in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="backend.Stacking.html#restore_float_callee_save">restore_float_callee_save</a> [definition, in <a href="backend.Stacking.html">backend.Stacking</a>]<br/>
-<a href="backend.Stackingproof.html#restore_float_callee_save_correct">restore_float_callee_save_correct</a> [lemma, in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="backend.Stackingproof.html#restore_float_callee_save_correct_rec">restore_float_callee_save_correct_rec</a> [lemma, in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="backend.Stacking.html#restore_int_callee_save">restore_int_callee_save</a> [definition, in <a href="backend.Stacking.html">backend.Stacking</a>]<br/>
-<a href="backend.Stackingproof.html#restore_int_callee_save_correct">restore_int_callee_save_correct</a> [lemma, in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="backend.Stackingproof.html#restore_int_callee_save_correct_rec">restore_int_callee_save_correct_rec</a> [lemma, in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="backend.Kildall.html#result">result</a> [definition, in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Allocproof_aux.html#reswellFormed">reswellFormed</a> [definition, in <a href="backend.Allocproof_aux.html">backend.Allocproof_aux</a>]<br/>
-<a href="backend.RTLgen.html#ret">ret</a> [definition, in <a href="backend.RTLgen.html">backend.RTLgen</a>]<br/>
-<a href="backend.LTL.html#Return">Return</a> [constructor, in <a href="backend.LTL.html">backend.LTL</a>]<br/>
-<a href="backend.LTL.html#return_regs">return_regs</a> [definition, in <a href="backend.LTL.html">backend.LTL</a>]<br/>
-<a href="backend.Allocproof.html#return_regs_not_destroyed">return_regs_not_destroyed</a> [lemma, in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.Allocproof.html#return_regs_result">return_regs_result</a> [lemma, in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.RTLgenproof1.html#return_reg_ok">return_reg_ok</a> [inductive, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#return_reg_ok_incr">return_reg_ok_incr</a> [lemma, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#return_reg_ok_none">return_reg_ok_none</a> [constructor, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#return_reg_ok_some">return_reg_ok_some</a> [constructor, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgen.html#ret_reg">ret_reg</a> [definition, in <a href="backend.RTLgen.html">backend.RTLgen</a>]<br/>
-<a href="backend.CSE.html#rhs">rhs</a> [inductive, in <a href="backend.CSE.html">backend.CSE</a>]<br/>
-<a href="backend.CSEproof.html#rhs_evals_to">rhs_evals_to</a> [definition, in <a href="backend.CSEproof.html">backend.CSEproof</a>]<br/>
-<a href="backend.Parallelmove.html#right">right</a> [definition, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="lib.Maps.html#rleaf">rleaf</a> [lemma, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Integers.html#rlw_accepting">rlw_accepting</a> [definition, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#RLW_Sbad">RLW_Sbad</a> [constructor, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#rlw_state">rlw_state</a> [inductive, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#RLW_S0">RLW_S0</a> [constructor, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#RLW_S1">RLW_S1</a> [constructor, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#RLW_S2">RLW_S2</a> [constructor, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#RLW_S3">RLW_S3</a> [constructor, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#RLW_S4">RLW_S4</a> [constructor, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#RLW_S5">RLW_S5</a> [constructor, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#RLW_S6">RLW_S6</a> [constructor, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#rlw_transition">rlw_transition</a> [definition, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#rol">rol</a> [definition, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Values.html#rolm">rolm</a> [definition, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Cmconstr.html#rolm">rolm</a> [definition, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="lib.Integers.html#rolm">rolm</a> [definition, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Cmconstr.html#rolm_cases">rolm_cases</a> [inductive, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#rolm_case1">rolm_case1</a> [constructor, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#rolm_case2">rolm_case2</a> [constructor, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#rolm_default">rolm_default</a> [constructor, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#rolm_match">rolm_match</a> [definition, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="lib.Integers.html#rolm_rolm">rolm_rolm</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Values.html#rolm_rolm">rolm_rolm</a> [lemma, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="lib.Integers.html#rolm_zero">rolm_zero</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Values.html#rolm_zero">rolm_zero</a> [lemma, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="lib.Integers.html#rol_and">rol_and</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#rol_or">rol_or</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#rol_rol">rol_rol</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#rol_zero">rol_zero</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.RTL.html">RTL</a> [library]<br/>
-<a href="backend.RTLgen.html">RTLgen</a> [library]<br/>
-<a href="backend.RTLgenproof.html">RTLgenproof</a> [library]<br/>
-<a href="backend.RTLgenproof1.html">RTLgenproof1</a> [library]<br/>
-<a href="backend.RTLtyping.html">RTLtyping</a> [library]<br/>
-<a href="backend.Locations.html#R10">R10</a> [constructor, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#R13">R13</a> [constructor, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#R14">R14</a> [constructor, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#R15">R15</a> [constructor, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#R16">R16</a> [constructor, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#R17">R17</a> [constructor, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#R18">R18</a> [constructor, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#R19">R19</a> [constructor, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Op.html#r2">r2</a> [constructor, in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Op.html#r2">r2</a> [constructor, in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Locations.html#R20">R20</a> [constructor, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#R21">R21</a> [constructor, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#R22">R22</a> [constructor, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#R23">R23</a> [constructor, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#R24">R24</a> [constructor, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#R25">R25</a> [constructor, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#R26">R26</a> [constructor, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#R27">R27</a> [constructor, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#R28">R28</a> [constructor, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#R29">R29</a> [constructor, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#R3">R3</a> [constructor, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#R30">R30</a> [constructor, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#R31">R31</a> [constructor, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#R4">R4</a> [constructor, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#R5">R5</a> [constructor, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#R6">R6</a> [constructor, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#R7">R7</a> [constructor, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#R8">R8</a> [constructor, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#R9">R9</a> [constructor, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<br/><br/><a name="global_S"></a><h2>S </h2>
-<a href="backend.Locations.html#S">S</a> [constructor, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="lib.union_find.html#sameclass">sameclass</a> [definition, in <a href="lib.union_find.html">lib.union_find</a>]<br/>
-<a href="lib.union_find.html#sameclass">sameclass</a> [definition, in <a href="lib.union_find.html">lib.union_find</a>]<br/>
-<a href="lib.union_find.html#sameclass_empty">sameclass_empty</a> [lemma, in <a href="lib.union_find.html">lib.union_find</a>]<br/>
-<a href="lib.union_find.html#sameclass_identify_1">sameclass_identify_1</a> [lemma, in <a href="lib.union_find.html">lib.union_find</a>]<br/>
-<a href="lib.union_find.html#sameclass_identify_2">sameclass_identify_2</a> [lemma, in <a href="lib.union_find.html">lib.union_find</a>]<br/>
-<a href="lib.union_find.html#sameclass_refl">sameclass_refl</a> [lemma, in <a href="lib.union_find.html">lib.union_find</a>]<br/>
-<a href="lib.union_find.html#sameclass_repr">sameclass_repr</a> [lemma, in <a href="lib.union_find.html">lib.union_find</a>]<br/>
-<a href="lib.union_find.html#sameclass_sym">sameclass_sym</a> [lemma, in <a href="lib.union_find.html">lib.union_find</a>]<br/>
-<a href="lib.union_find.html#sameclass_trans">sameclass_trans</a> [lemma, in <a href="lib.union_find.html">lib.union_find</a>]<br/>
-<a href="backend.Parallelmove.html#sameEnv">sameEnv</a> [definition, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#sameExec">sameExec</a> [definition, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#sameExec_reflexive">sameExec_reflexive</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#sameExec_transitive">sameExec_transitive</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Cmconstr.html#same_expr_pure">same_expr_pure</a> [definition, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Locations.html#same_not_diff">same_not_diff</a> [lemma, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Coloring.html#same_typ">same_typ</a> [definition, in <a href="backend.Coloring.html">backend.Coloring</a>]<br/>
-<a href="backend.Coloringproof.html#same_typ_correct">same_typ_correct</a> [lemma, in <a href="backend.Coloringproof.html">backend.Coloringproof</a>]<br/>
-<a href="backend.Stacking.html#save_callee_save">save_callee_save</a> [definition, in <a href="backend.Stacking.html">backend.Stacking</a>]<br/>
-<a href="backend.Stackingproof.html#save_callee_save_correct">save_callee_save_correct</a> [lemma, in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="backend.Stacking.html#save_float_callee_save">save_float_callee_save</a> [definition, in <a href="backend.Stacking.html">backend.Stacking</a>]<br/>
-<a href="backend.Stackingproof.html#save_float_callee_save_correct">save_float_callee_save_correct</a> [lemma, in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="backend.Stackingproof.html#save_float_callee_save_correct_rec">save_float_callee_save_correct_rec</a> [lemma, in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="backend.Stacking.html#save_int_callee_save">save_int_callee_save</a> [definition, in <a href="backend.Stacking.html">backend.Stacking</a>]<br/>
-<a href="backend.Stackingproof.html#save_int_callee_save_correct">save_int_callee_save_correct</a> [lemma, in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="backend.Stackingproof.html#save_int_callee_save_correct_rec">save_int_callee_save_correct_rec</a> [lemma, in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="backend.Cminor.html#Sblock">Sblock</a> [constructor, in <a href="backend.Cminor.html">backend.Cminor</a>]<br/>
-<a href="backend.Csharpminor.html#Sblock">Sblock</a> [constructor, in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Parallelmove.html#SB_Pmov">SB_Pmov</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Cminor.html#Scons">Scons</a> [constructor, in <a href="backend.Cminor.html">backend.Cminor</a>]<br/>
-<a href="backend.Csharpminor.html#Scons">Scons</a> [constructor, in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Allocproof_aux.html#SDone_Pmov">SDone_Pmov</a> [lemma, in <a href="backend.Allocproof_aux.html">backend.Allocproof_aux</a>]<br/>
-<a href="backend.Allocproof_aux.html#SDone_stepf">SDone_stepf</a> [lemma, in <a href="backend.Allocproof_aux.html">backend.Allocproof_aux</a>]<br/>
-<a href="backend.Parallelmove.html#sD_nW">sD_nW</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#sD_pexec">sD_pexec</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="lib.Lattice.html#SEMILATTICE">SEMILATTICE</a> [module, in <a href="lib.Lattice.html">lib.Lattice</a>]<br/>
-<a href="lib.Lattice.html#SEMILATTICE_WITH_TOP">SEMILATTICE_WITH_TOP</a> [module, in <a href="lib.Lattice.html">lib.Lattice</a>]<br/>
-<a href="lib.Maps.html#set">set</a> [definition, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="backend.Locations.html#set">set</a> [definition, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="lib.Maps.html#set">set</a> [definition, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#set">set</a> [definition, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Lattice.html#set">set</a> [definition, in <a href="lib.Lattice.html">lib.Lattice</a>]<br/>
-<a href="lib.Maps.html#set">set</a> [definition, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="backend.InterfGraph.html#SetDepRegMreg">SetDepRegMreg</a> [module, in <a href="backend.InterfGraph.html">backend.InterfGraph</a>]<br/>
-<a href="backend.InterfGraph.html#SetDepRegReg">SetDepRegReg</a> [module, in <a href="backend.InterfGraph.html">backend.InterfGraph</a>]<br/>
-<a href="backend.Mem.html#setN">setN</a> [definition, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#setN_agree">setN_agree</a> [lemma, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#setN_inject">setN_inject</a> [lemma, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#setN_outside_agree">setN_outside_agree</a> [lemma, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#setN_outside_inject">setN_outside_inject</a> [lemma, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.InterfGraph.html#SetRegMreg">SetRegMreg</a> [module, in <a href="backend.InterfGraph.html">backend.InterfGraph</a>]<br/>
-<a href="backend.InterfGraph.html#SetRegReg">SetRegReg</a> [module, in <a href="backend.InterfGraph.html">backend.InterfGraph</a>]<br/>
-<a href="lib.Sets.html">Sets</a> [library]<br/>
-<a href="backend.Mem.html#set_cont">set_cont</a> [definition, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#set_cont_agree">set_cont_agree</a> [lemma, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#set_cont_inject">set_cont_inject</a> [lemma, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#set_cont_inside">set_cont_inside</a> [lemma, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#set_cont_outside">set_cont_outside</a> [lemma, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#set_cont_outside1">set_cont_outside1</a> [lemma, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#set_cont_outside_agree">set_cont_outside_agree</a> [lemma, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#set_cont_outside_inject">set_cont_outside_inject</a> [lemma, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Cminor.html#set_locals">set_locals</a> [definition, in <a href="backend.Cminor.html">backend.Cminor</a>]<br/>
-<a href="backend.Cminorgenproof.html#set_locals_defined">set_locals_defined</a> [lemma, in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#set_locals_params_defined">set_locals_params_defined</a> [lemma, in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Cminor.html#set_params">set_params</a> [definition, in <a href="backend.Cminor.html">backend.Cminor</a>]<br/>
-<a href="backend.Cminorgenproof.html#set_params_defined">set_params_defined</a> [lemma, in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Machabstr.html#set_slot">set_slot</a> [inductive, in <a href="backend.Machabstr.html">backend.Machabstr</a>]<br/>
-<a href="backend.Stackingproof.html#set_slot_index">set_slot_index</a> [lemma, in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="backend.Machabstr.html#set_slot_intro">set_slot_intro</a> [constructor, in <a href="backend.Machabstr.html">backend.Machabstr</a>]<br/>
-<a href="backend.Machtyping.html#set_slot_link_invariant">set_slot_link_invariant</a> [lemma, in <a href="backend.Machtyping.html">backend.Machtyping</a>]<br/>
-<a href="backend.Stackingproof.html#set_slot_ok">set_slot_ok</a> [lemma, in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="backend.Parallelmove.html#Sexec">Sexec</a> [definition, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#sexec">sexec</a> [definition, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Cminor.html#Sexit">Sexit</a> [constructor, in <a href="backend.Cminor.html">backend.Cminor</a>]<br/>
-<a href="backend.Csharpminor.html#Sexit">Sexit</a> [constructor, in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Cminor.html#Sexpr">Sexpr</a> [constructor, in <a href="backend.Cminor.html">backend.Cminor</a>]<br/>
-<a href="backend.Csharpminor.html#Sexpr">Sexpr</a> [constructor, in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Cmconstr.html#shift_cases">shift_cases</a> [inductive, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#shift_case1">shift_case1</a> [constructor, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#shift_default">shift_default</a> [constructor, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Stackingproof.html#shift_eval_addressing">shift_eval_addressing</a> [lemma, in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="backend.Stackingproof.html#shift_eval_operation">shift_eval_operation</a> [lemma, in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="backend.Cmconstr.html#shift_match">shift_match</a> [definition, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Stackingproof.html#shift_sp">shift_sp</a> [definition, in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="lib.Integers.html#shl">shl</a> [definition, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Cmconstr.html#shl">shl</a> [definition, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Values.html#shl">shl</a> [definition, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Cmconstr.html#shlimm">shlimm</a> [definition, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Values.html#shl_mul">shl_mul</a> [lemma, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="lib.Integers.html#shl_mul">shl_mul</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#shl_mul_two_p">shl_mul_two_p</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#shl_rolm">shl_rolm</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Values.html#shl_rolm">shl_rolm</a> [lemma, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="lib.Integers.html#shl_zero">shl_zero</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#shr">shr</a> [definition, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Cmconstr.html#shr">shr</a> [definition, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Values.html#shr">shr</a> [definition, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Cmconstr.html#shru">shru</a> [definition, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="lib.Integers.html#shru">shru</a> [definition, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Values.html#shru">shru</a> [definition, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Cmconstr.html#shruimm">shruimm</a> [definition, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="lib.Integers.html#shru_div_two_p">shru_div_two_p</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Values.html#shru_rolm">shru_rolm</a> [lemma, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="lib.Integers.html#shru_rolm">shru_rolm</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#shru_zero">shru_zero</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#shrx">shrx</a> [definition, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Values.html#shrx">shrx</a> [definition, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Values.html#shrx_carry">shrx_carry</a> [lemma, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="lib.Integers.html#shrx_carry">shrx_carry</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Values.html#shr_carry">shr_carry</a> [definition, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="lib.Integers.html#shr_carry">shr_carry</a> [definition, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#shr_zero">shr_zero</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Csharpminor.html#Sifthenelse">Sifthenelse</a> [constructor, in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Cminor.html#Sifthenelse">Sifthenelse</a> [constructor, in <a href="backend.Cminor.html">backend.Cminor</a>]<br/>
-<a href="backend.AST.html#signature">signature</a> [inductive, in <a href="backend.AST.html">backend.AST</a>]<br/>
-<a href="lib.Integers.html#signed">signed</a> [definition, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#signed_range">signed_range</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#signed_repr">signed_repr</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Allocproof.html#sig_function_translated">sig_function_translated</a> [lemma, in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#sig_transl_function">sig_transl_function</a> [lemma, in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Parallelmove.html#simpleDest">simpleDest</a> [definition, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#simpleDest_insert">simpleDest_insert</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#simpleDest_movBack">simpleDest_movBack</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#simpleDest_movFront">simpleDest_movFront</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#simpleDest_Pop">simpleDest_Pop</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#simpleDest_pop">simpleDest_pop</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#simpleDest_pop2">simpleDest_pop2</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#simpleDest_right">simpleDest_right</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#simpleDest_swap">simpleDest_swap</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#simpleDest_swap_app">simpleDest_swap_app</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#simpleDest_tmpLast">simpleDest_tmpLast</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Values.html#singleoffloat">singleoffloat</a> [definition, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Cmconstr.html#singleoffloat">singleoffloat</a> [definition, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="lib.Floats.html#singleoffloat">singleoffloat</a> [axiom, in <a href="lib.Floats.html">lib.Floats</a>]<br/>
-<a href="lib.Floats.html#singleoffloat_idem">singleoffloat_idem</a> [axiom, in <a href="lib.Floats.html">lib.Floats</a>]<br/>
-<a href="backend.Csharpminor.html#sizeof">sizeof</a> [definition, in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Mem.html#Size16">Size16</a> [constructor, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#Size32">Size32</a> [constructor, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#Size64">Size64</a> [constructor, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#Size8">Size8</a> [constructor, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Conventions.html#size_arguments">size_arguments</a> [definition, in <a href="backend.Conventions.html">backend.Conventions</a>]<br/>
-<a href="backend.Linearizetyping.html#size_arguments_bound">size_arguments_bound</a> [lemma, in <a href="backend.Linearizetyping.html">backend.Linearizetyping</a>]<br/>
-<a href="backend.Conventions.html#size_arguments_rec">size_arguments_rec</a> [definition, in <a href="backend.Conventions.html">backend.Conventions</a>]<br/>
-<a href="backend.Mem.html#size_chunk">size_chunk</a> [definition, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#size_chunk_pos">size_chunk_pos</a> [lemma, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#size_mem">size_mem</a> [definition, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#size_mem_pos">size_mem_pos</a> [lemma, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Stackingproof.html#size_no_overflow">size_no_overflow</a> [lemma, in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="backend.Stackingproof.html#size_pos">size_pos</a> [lemma, in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="backend.Csharpminor.html#Sloop">Sloop</a> [constructor, in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Cminor.html#Sloop">Sloop</a> [constructor, in <a href="backend.Cminor.html">backend.Cminor</a>]<br/>
-<a href="backend.Locations.html#slot">slot</a> [inductive, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Lineartyping.html#slots_of_instr">slots_of_instr</a> [definition, in <a href="backend.Lineartyping.html">backend.Lineartyping</a>]<br/>
-<a href="backend.Lineartyping.html#slot_bounded">slot_bounded</a> [definition, in <a href="backend.Lineartyping.html">backend.Lineartyping</a>]<br/>
-<a href="backend.LTLtyping.html#slot_bounded">slot_bounded</a> [definition, in <a href="backend.LTLtyping.html">backend.LTLtyping</a>]<br/>
-<a href="backend.Locations.html#slot_eq">slot_eq</a> [lemma, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Stackingproof.html#slot_gi">slot_gi</a> [lemma, in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="backend.Stackingproof.html#slot_gso">slot_gso</a> [lemma, in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="backend.Stackingproof.html#slot_gss">slot_gss</a> [lemma, in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="backend.Stackingproof.html#slot_iso">slot_iso</a> [lemma, in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="backend.Stackingproof.html#slot_iss">slot_iss</a> [lemma, in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="backend.Linearizetyping.html#slot_is_bounded">slot_is_bounded</a> [lemma, in <a href="backend.Linearizetyping.html">backend.Linearizetyping</a>]<br/>
-<a href="backend.Locations.html#slot_type">slot_type</a> [definition, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Csharpminor.html#Snil">Snil</a> [constructor, in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Cminor.html#Snil">Snil</a> [constructor, in <a href="backend.Cminor.html">backend.Cminor</a>]<br/>
-<a href="backend.CSE.html#Solver">Solver</a> [module, in <a href="backend.CSE.html">backend.CSE</a>]<br/>
-<a href="backend.Parallelmove.html#Some">Some</a> [definition, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="lib.Inclusion.html#sort_bin">sort_bin</a> [definition, in <a href="lib.Inclusion.html">lib.Inclusion</a>]<br/>
-<a href="lib.Inclusion.html#sort_included">sort_included</a> [lemma, in <a href="lib.Inclusion.html">lib.Inclusion</a>]<br/>
-<a href="lib.Inclusion.html#sort_included2">sort_included2</a> [lemma, in <a href="lib.Inclusion.html">lib.Inclusion</a>]<br/>
-<a href="backend.Parallelmove.html#splitNone">splitNone</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#splitSome">splitSome</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#split_length">split_length</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#split_move">split_move</a> [definition, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#split_move'">split_move'</a> [definition, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Alloctyping_aux.html#split_move_incl">split_move_incl</a> [lemma, in <a href="backend.Alloctyping_aux.html">backend.Alloctyping_aux</a>]<br/>
-<a href="backend.PPCgenproof1.html#sp_val">sp_val</a> [lemma, in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.Alloctyping_aux.html#srcdst_tmp2_stepf">srcdst_tmp2_stepf</a> [lemma, in <a href="backend.Alloctyping_aux.html">backend.Alloctyping_aux</a>]<br/>
-<a href="backend.Alloctyping_aux.html#src_tmp2_res">src_tmp2_res</a> [lemma, in <a href="backend.Alloctyping_aux.html">backend.Alloctyping_aux</a>]<br/>
-<a href="backend.Csharpminor.html#Sreturn">Sreturn</a> [constructor, in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Cminor.html#Sreturn">Sreturn</a> [constructor, in <a href="backend.Cminor.html">backend.Cminor</a>]<br/>
-<a href="backend.Stacking.html">Stacking</a> [library]<br/>
-<a href="backend.Stackingproof.html">Stackingproof</a> [library]<br/>
-<a href="backend.Stackingtyping.html">Stackingtyping</a> [library]<br/>
-<a href="backend.Linearize.html#starts_with">starts_with</a> [definition, in <a href="backend.Linearize.html">backend.Linearize</a>]<br/>
-<a href="backend.Linearizeproof.html#starts_with_correct">starts_with_correct</a> [lemma, in <a href="backend.Linearizeproof.html">backend.Linearizeproof</a>]<br/>
-<a href="backend.Kildall.html#start_state">start_state</a> [definition, in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Kildall.html#start_state_good">start_state_good</a> [lemma, in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Kildall.html#start_state_in">start_state_in</a> [definition, in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Kildall.html#start_state_in_entry">start_state_in_entry</a> [lemma, in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Kildall.html#start_state_wrk">start_state_wrk</a> [definition, in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Kildall.html#state">state</a> [inductive, in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Parallelmove.html#State">State</a> [definition, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.RTLgen.html#state">state</a> [inductive, in <a href="backend.RTLgen.html">backend.RTLgen</a>]<br/>
-<a href="backend.Kildall.html#state">state</a> [inductive, in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Parallelmove.html#StateBeing">StateBeing</a> [definition, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#StateDone">StateDone</a> [definition, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#StateToMove">StateToMove</a> [definition, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.RTLgenproof1.html#state_extends">state_extends</a> [definition, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#state_incr">state_incr</a> [inductive, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#state_incr_extends">state_incr_extends</a> [lemma, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#state_incr_intro">state_incr_intro</a> [constructor, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#state_incr_refl">state_incr_refl</a> [lemma, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#state_incr_trans">state_incr_trans</a> [lemma, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#state_incr_trans2">state_incr_trans2</a> [lemma, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#state_incr_trans3">state_incr_trans3</a> [lemma, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#state_incr_trans4">state_incr_trans4</a> [lemma, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#state_incr_trans5">state_incr_trans5</a> [lemma, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#state_incr_trans6">state_incr_trans6</a> [lemma, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.Kildall.html#state_invariant">state_invariant</a> [definition, in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Kildall.html#step">step</a> [definition, in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Parallelmove.html#step">step</a> [inductive, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Kildall.html#step">step</a> [definition, in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Parallelmove.html#stepf">stepf</a> [definition, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#stepf'">stepf'</a> [definition, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#stepf1_dec">stepf1_dec</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#stepf_dec">stepf_dec</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#stepf_dec0">stepf_dec0</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#stepf_dec0'">stepf_dec0'</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#stepf_pop">stepf_pop</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#stepf_popLoop">stepf_popLoop</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#stepInv">stepInv</a> [definition, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Allocproof_aux.html#stepInv_pnilnil">stepInv_pnilnil</a> [lemma, in <a href="backend.Allocproof_aux.html">backend.Allocproof_aux</a>]<br/>
-<a href="backend.Parallelmove.html#stepp">stepp</a> [inductive, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#stepp_inv">stepp_inv</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#stepp_refl">stepp_refl</a> [constructor, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#stepp_sameExec">stepp_sameExec</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#stepp_trans">stepp_trans</a> [constructor, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#stepp_transitive">stepp_transitive</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.RTLtyping.html#step1">step1</a> [lemma, in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.RTLtyping.html#step2">step2</a> [lemma, in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.RTLtyping.html#step3">step3</a> [lemma, in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.RTLtyping.html#step4">step4</a> [lemma, in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.Parallelmove.html#step_dec">step_dec</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#step_dec0">step_dec0</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#step_inv">step_inv</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#step_inv_getdst">step_inv_getdst</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#step_inv_loop">step_inv_loop</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#step_inv_loop_aux">step_inv_loop_aux</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#step_inv_noOverlap">step_inv_noOverlap</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#step_inv_NoOverlap">step_inv_NoOverlap</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#step_inv_noTmp">step_inv_noTmp</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#step_inv_noTmpLast">step_inv_noTmpLast</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#step_inv_path">step_inv_path</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#step_inv_simpleDest">step_inv_simpleDest</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#step_loop">step_loop</a> [constructor, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#step_NF">step_NF</a> [definition, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#step_nop">step_nop</a> [constructor, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#step_pop">step_pop</a> [constructor, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#step_push">step_push</a> [constructor, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#step_sameExec">step_sameExec</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#step_start">step_start</a> [constructor, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Kildall.html#step_state_good">step_state_good</a> [lemma, in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Parallelmove.html#step_stepp">step_stepp</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Csharpminor.html#stmt">stmt</a> [inductive, in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Cminor.html#stmt">stmt</a> [inductive, in <a href="backend.Cminor.html">backend.Cminor</a>]<br/>
-<a href="backend.Csharpminor.html#stmtlist">stmtlist</a> [inductive, in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Cminor.html#stmtlist">stmtlist</a> [inductive, in <a href="backend.Cminor.html">backend.Cminor</a>]<br/>
-<a href="backend.RTLgenproof1.html#stmt_stmtlist_ind">stmt_stmtlist_ind</a> [lemma, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.Parallelmove.html#STM_Pmov">STM_Pmov</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Cmconstr.html#store">store</a> [definition, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Mem.html#store">store</a> [definition, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.PPCgen.html#storeind">storeind</a> [definition, in <a href="backend.PPCgen.html">backend.PPCgen</a>]<br/>
-<a href="backend.PPCgen.html#storeind_aux">storeind_aux</a> [definition, in <a href="backend.PPCgen.html">backend.PPCgen</a>]<br/>
-<a href="backend.PPCgenproof1.html#storeind_aux_correct">storeind_aux_correct</a> [lemma, in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.PPCgenproof1.html#storeind_correct">storeind_correct</a> [lemma, in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.Mem.html#storev">storev</a> [definition, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#storev_mapped_inject">storev_mapped_inject</a> [lemma, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#storev_mapped_inject_1">storev_mapped_inject_1</a> [lemma, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.PPCgenproof.html#storev_16_signed_unsigned">storev_16_signed_unsigned</a> [lemma, in <a href="backend.PPCgenproof.html">backend.PPCgenproof</a>]<br/>
-<a href="backend.PPCgenproof.html#storev_8_signed_unsigned">storev_8_signed_unsigned</a> [lemma, in <a href="backend.PPCgenproof.html">backend.PPCgenproof</a>]<br/>
-<a href="backend.PPC.html#store1">store1</a> [definition, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#store2">store2</a> [definition, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.Mem.html#store_agree">store_agree</a> [lemma, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#store_alloc">store_alloc</a> [lemma, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#store_contentmap_agree">store_contentmap_agree</a> [lemma, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#store_contentmap_outside_agree">store_contentmap_outside_agree</a> [lemma, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#store_contents">store_contents</a> [definition, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#store_contents_inject">store_contents_inject</a> [lemma, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#store_contents_outside_inject">store_contents_outside_inject</a> [lemma, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#store_inv">store_inv</a> [lemma, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#store_in_bounds">store_in_bounds</a> [lemma, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#store_is_in_bounds">store_is_in_bounds</a> [lemma, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#store_mapped_inject">store_mapped_inject</a> [lemma, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#store_mapped_inject_1">store_mapped_inject_1</a> [lemma, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#store_outside_agree">store_outside_agree</a> [lemma, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#store_outside_extends">store_outside_extends</a> [lemma, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Cminorgen.html#store_parameters">store_parameters</a> [definition, in <a href="backend.Cminorgen.html">backend.Cminorgen</a>]<br/>
-<a href="backend.Cminorgenproof.html#store_parameters_correct">store_parameters_correct</a> [lemma, in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Mach.html#store_stack">store_stack</a> [definition, in <a href="backend.Mach.html">backend.Mach</a>]<br/>
-<a href="backend.Mem.html#store_unmapped_inject">store_unmapped_inject</a> [lemma, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#store_within_extends">store_within_extends</a> [lemma, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="lib.Floats.html#sub">sub</a> [axiom, in <a href="lib.Floats.html">lib.Floats</a>]<br/>
-<a href="backend.Values.html#sub">sub</a> [definition, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="lib.Integers.html#sub">sub</a> [definition, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Cmconstr.html#sub">sub</a> [definition, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Values.html#subf">subf</a> [definition, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Cmconstr.html#subf">subf</a> [definition, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="lib.Floats.html#subf_addf_opp">subf_addf_opp</a> [axiom, in <a href="lib.Floats.html">lib.Floats</a>]<br/>
-<a href="backend.Cmconstr.html#subf_cases">subf_cases</a> [inductive, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#subf_case1">subf_case1</a> [constructor, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#subf_default">subf_default</a> [constructor, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#subf_match">subf_match</a> [definition, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Machtyping.html#subject_reduction">subject_reduction</a> [lemma, in <a href="backend.Machtyping.html">backend.Machtyping</a>]<br/>
-<a href="backend.RTLtyping.html#subject_reduction">subject_reduction</a> [lemma, in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.Machtyping.html#subject_reduction_function">subject_reduction_function</a> [lemma, in <a href="backend.Machtyping.html">backend.Machtyping</a>]<br/>
-<a href="backend.Machtyping.html#subject_reduction_instr">subject_reduction_instr</a> [lemma, in <a href="backend.Machtyping.html">backend.Machtyping</a>]<br/>
-<a href="backend.Machtyping.html#subject_reduction_instrs">subject_reduction_instrs</a> [lemma, in <a href="backend.Machtyping.html">backend.Machtyping</a>]<br/>
-<a href="backend.Values.html#sub_add_l">sub_add_l</a> [lemma, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="lib.Integers.html#sub_add_l">sub_add_l</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#sub_add_opp">sub_add_opp</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Values.html#sub_add_opp">sub_add_opp</a> [lemma, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Values.html#sub_add_r">sub_add_r</a> [lemma, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="lib.Integers.html#sub_add_r">sub_add_r</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Cmconstr.html#sub_cases">sub_cases</a> [inductive, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#sub_case1">sub_case1</a> [constructor, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#sub_case2">sub_case2</a> [constructor, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#sub_case3">sub_case3</a> [constructor, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#sub_case4">sub_case4</a> [constructor, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#sub_default">sub_default</a> [constructor, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="lib.Integers.html#sub_idem">sub_idem</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Cmconstr.html#sub_match">sub_match</a> [definition, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#sub_match_aux">sub_match_aux</a> [definition, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="lib.Integers.html#sub_shifted">sub_shifted</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#sub_zero_l">sub_zero_l</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Values.html#sub_zero_r">sub_zero_r</a> [lemma, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="lib.Integers.html#sub_zero_r">sub_zero_r</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.LTL.html#successors">successors</a> [definition, in <a href="backend.LTL.html">backend.LTL</a>]<br/>
-<a href="backend.RTL.html#successors">successors</a> [definition, in <a href="backend.RTL.html">backend.RTL</a>]<br/>
-<a href="backend.LTL.html#successors_aux">successors_aux</a> [definition, in <a href="backend.LTL.html">backend.LTL</a>]<br/>
-<a href="backend.LTL.html#successors_aux_invariant">successors_aux_invariant</a> [lemma, in <a href="backend.LTL.html">backend.LTL</a>]<br/>
-<a href="backend.LTL.html#successors_correct">successors_correct</a> [lemma, in <a href="backend.LTL.html">backend.LTL</a>]<br/>
-<a href="backend.RTL.html#successors_correct">successors_correct</a> [lemma, in <a href="backend.RTL.html">backend.RTL</a>]<br/>
-<a href="lib.Coqlib.html#sum_left_map">sum_left_map</a> [definition, in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Integers.html#swap_cmp">swap_cmp</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Values.html#swap_cmp">swap_cmp</a> [lemma, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Values.html#swap_cmpu">swap_cmpu</a> [lemma, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="lib.Integers.html#swap_cmpu">swap_cmpu</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Values.html#swap_cmp_mismatch">swap_cmp_mismatch</a> [lemma, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.AST.html#swap_comparison">swap_comparison</a> [definition, in <a href="backend.AST.html">backend.AST</a>]<br/>
-<a href="backend.Globalenvs.html#symbols_add_globals_transf">symbols_add_globals_transf</a> [lemma, in <a href="backend.Globalenvs.html">backend.Globalenvs</a>]<br/>
-<a href="backend.Globalenvs.html#symbols_init_transf">symbols_init_transf</a> [lemma, in <a href="backend.Globalenvs.html">backend.Globalenvs</a>]<br/>
-<a href="backend.Tunnelingproof.html#symbols_preserved">symbols_preserved</a> [lemma, in <a href="backend.Tunnelingproof.html">backend.Tunnelingproof</a>]<br/>
-<a href="backend.Allocproof.html#symbols_preserved">symbols_preserved</a> [lemma, in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#symbols_preserved">symbols_preserved</a> [lemma, in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Constpropproof.html#symbols_preserved">symbols_preserved</a> [lemma, in <a href="backend.Constpropproof.html">backend.Constpropproof</a>]<br/>
-<a href="backend.PPCgenproof.html#symbols_preserved">symbols_preserved</a> [lemma, in <a href="backend.PPCgenproof.html">backend.PPCgenproof</a>]<br/>
-<a href="backend.RTLgenproof.html#symbols_preserved">symbols_preserved</a> [lemma, in <a href="backend.RTLgenproof.html">backend.RTLgenproof</a>]<br/>
-<a href="backend.Linearizeproof.html#symbols_preserved">symbols_preserved</a> [lemma, in <a href="backend.Linearizeproof.html">backend.Linearizeproof</a>]<br/>
-<a href="backend.CSEproof.html#symbols_preserved">symbols_preserved</a> [lemma, in <a href="backend.CSEproof.html">backend.CSEproof</a>]<br/>
-<a href="backend.Stackingproof.html#symbols_preserved">symbols_preserved</a> [lemma, in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="backend.PPC.html#symbol_offset">symbol_offset</a> [definition, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.Linearize.html#s1">s1</a> [definition, in <a href="backend.Linearize.html">backend.Linearize</a>]<br/>
-<br/><br/><a name="global_T"></a><h2>T </h2>
-<a href="backend.PPC.html#t">t</a> [definition, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="lib.Ordered.html#t">t</a> [definition, in <a href="lib.Ordered.html">lib.Ordered</a>]<br/>
-<a href="lib.Maps.html#t">t</a> [definition, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#t">t</a> [definition, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Lattice.html#t">t</a> [definition, in <a href="lib.Lattice.html">lib.Lattice</a>]<br/>
-<a href="backend.Locations.html#t">t</a> [definition, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Constprop.html#t">t</a> [definition, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="lib.Ordered.html#t">t</a> [definition, in <a href="lib.Ordered.html">lib.Ordered</a>]<br/>
-<a href="backend.Globalenvs.html#t">t</a> [definition, in <a href="backend.Globalenvs.html">backend.Globalenvs</a>]<br/>
-<a href="lib.Lattice.html#t">t</a> [definition, in <a href="lib.Lattice.html">lib.Lattice</a>]<br/>
-<a href="backend.RTLtyping.html#T">T</a> [definition, in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="lib.union_find.html#T">T</a> [definition, in <a href="lib.union_find.html">lib.union_find</a>]<br/>
-<a href="backend.CSEproof.html#t">t</a> [definition, in <a href="backend.CSEproof.html">backend.CSEproof</a>]<br/>
-<a href="backend.Locations.html#t">t</a> [definition, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="lib.Maps.html#t">t</a> [definition, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="backend.Parallelmove.html#T">T</a> [definition, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="lib.Maps.html#t">t</a> [definition, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="backend.RTLtyping.html#T">T</a> [definition, in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.InterfGraph.html#t">t</a> [definition, in <a href="backend.InterfGraph.html">backend.InterfGraph</a>]<br/>
-<a href="lib.Maps.html#t">t</a> [definition, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Ordered.html#t">t</a> [definition, in <a href="lib.Ordered.html">lib.Ordered</a>]<br/>
-<a href="lib.Lattice.html#t">t</a> [definition, in <a href="lib.Lattice.html">lib.Lattice</a>]<br/>
-<a href="backend.Mach.html#t">t</a> [definition, in <a href="backend.Mach.html">backend.Mach</a>]<br/>
-<a href="lib.Sets.html#t">t</a> [definition, in <a href="lib.Sets.html">lib.Sets</a>]<br/>
-<a href="lib.Maps.html#t">t</a> [definition, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="backend.CSE.html#t">t</a> [definition, in <a href="backend.CSE.html">backend.CSE</a>]<br/>
-<a href="backend.RTLgenproof1.html#target_regs_cons">target_regs_cons</a> [constructor, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#target_regs_nil">target_regs_nil</a> [constructor, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#target_regs_not_mutated">target_regs_not_mutated</a> [lemma, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#target_regs_ok">target_regs_ok</a> [inductive, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#target_regs_ok_incr">target_regs_ok_incr</a> [lemma, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#target_regs_valid">target_regs_valid</a> [lemma, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#target_reg_immut_var">target_reg_immut_var</a> [constructor, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#target_reg_not_mutated">target_reg_not_mutated</a> [lemma, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#target_reg_ok">target_reg_ok</a> [inductive, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#target_reg_ok_incr">target_reg_ok_incr</a> [lemma, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#target_reg_valid">target_reg_valid</a> [lemma, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.Conventions.html#temporaries">temporaries</a> [definition, in <a href="backend.Conventions.html">backend.Conventions</a>]<br/>
-<a href="backend.Allocproof_aux.html#temporaries1">temporaries1</a> [definition, in <a href="backend.Allocproof_aux.html">backend.Allocproof_aux</a>]<br/>
-<a href="backend.Allocproof_aux.html#temporaries1_3">temporaries1_3</a> [definition, in <a href="backend.Allocproof_aux.html">backend.Allocproof_aux</a>]<br/>
-<a href="backend.Allocproof_aux.html#temporaries2">temporaries2</a> [definition, in <a href="backend.Allocproof_aux.html">backend.Allocproof_aux</a>]<br/>
-<a href="backend.Conventions.html#temporaries_not_acceptable">temporaries_not_acceptable</a> [lemma, in <a href="backend.Conventions.html">backend.Conventions</a>]<br/>
-<a href="backend.RTLtyping.html#teq">teq</a> [definition, in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.RTLtyping.html#teq_correct">teq_correct</a> [lemma, in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="lib.Inclusion.html#test_inclusion">test_inclusion</a> [definition, in <a href="lib.Inclusion.html">lib.Inclusion</a>]<br/>
-<a href="lib.Inclusion.html#test_inclusion_sound">test_inclusion_sound</a> [lemma, in <a href="lib.Inclusion.html">lib.Inclusion</a>]<br/>
-<a href="backend.AST.html#Tfloat">Tfloat</a> [constructor, in <a href="backend.AST.html">backend.AST</a>]<br/>
-<a href="backend.Allocation.html#Tint">Tint</a> [definition, in <a href="backend.Allocation.html">backend.Allocation</a>]<br/>
-<a href="backend.AST.html#Tint">Tint</a> [constructor, in <a href="backend.AST.html">backend.AST</a>]<br/>
-<a href="lib.Lattice.html#top">top</a> [definition, in <a href="lib.Lattice.html">lib.Lattice</a>]<br/>
-<a href="lib.Lattice.html#top">top</a> [definition, in <a href="lib.Lattice.html">lib.Lattice</a>]<br/>
-<a href="backend.CSE.html#top">top</a> [definition, in <a href="backend.CSE.html">backend.CSE</a>]<br/>
-<a href="backend.Constprop.html#top">top</a> [definition, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="lib.Lattice.html#top">top</a> [definition, in <a href="lib.Lattice.html">lib.Lattice</a>]<br/>
-<a href="backend.CSE.html#top_ge">top_ge</a> [lemma, in <a href="backend.CSE.html">backend.CSE</a>]<br/>
-<a href="backend.Allocation.html#transfer">transfer</a> [definition, in <a href="backend.Allocation.html">backend.Allocation</a>]<br/>
-<a href="backend.Constprop.html#transfer">transfer</a> [definition, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.CSE.html#transfer">transfer</a> [definition, in <a href="backend.CSE.html">backend.CSE</a>]<br/>
-<a href="backend.Constpropproof.html#transfer_correct">transfer_correct</a> [lemma, in <a href="backend.Constpropproof.html">backend.Constpropproof</a>]<br/>
-<a href="backend.CSEproof.html#transfer_correct">transfer_correct</a> [lemma, in <a href="backend.CSEproof.html">backend.CSEproof</a>]<br/>
-<a href="backend.AST.html#transform_partial_program">transform_partial_program</a> [definition, in <a href="backend.AST.html">backend.AST</a>]<br/>
-<a href="backend.Main.html#transform_partial_program_compose">transform_partial_program_compose</a> [lemma, in <a href="backend.Main.html">backend.Main</a>]<br/>
-<a href="backend.AST.html#transform_partial_program_function">transform_partial_program_function</a> [lemma, in <a href="backend.AST.html">backend.AST</a>]<br/>
-<a href="backend.AST.html#transform_partial_program_main">transform_partial_program_main</a> [lemma, in <a href="backend.AST.html">backend.AST</a>]<br/>
-<a href="backend.AST.html#transform_program">transform_program</a> [definition, in <a href="backend.AST.html">backend.AST</a>]<br/>
-<a href="backend.AST.html#transform_program_function">transform_program_function</a> [lemma, in <a href="backend.AST.html">backend.AST</a>]<br/>
-<a href="backend.Main.html#transform_program_partial_total">transform_program_partial_total</a> [lemma, in <a href="backend.Main.html">backend.Main</a>]<br/>
-<a href="backend.Globalenvs.html#transform_program_transform_partial_program">transform_program_transform_partial_program</a> [lemma, in <a href="backend.Globalenvs.html">backend.Globalenvs</a>]<br/>
-<a href="backend.Main.html#transf_cminor_function">transf_cminor_function</a> [definition, in <a href="backend.Main.html">backend.Main</a>]<br/>
-<a href="backend.Main.html#transf_cminor_program">transf_cminor_program</a> [definition, in <a href="backend.Main.html">backend.Main</a>]<br/>
-<a href="backend.Main.html#transf_cminor_program2">transf_cminor_program2</a> [definition, in <a href="backend.Main.html">backend.Main</a>]<br/>
-<a href="backend.Main.html#transf_cminor_program2_correct">transf_cminor_program2_correct</a> [lemma, in <a href="backend.Main.html">backend.Main</a>]<br/>
-<a href="backend.Main.html#transf_cminor_program_correct">transf_cminor_program_correct</a> [lemma, in <a href="backend.Main.html">backend.Main</a>]<br/>
-<a href="backend.Main.html#transf_cminor_program_equiv">transf_cminor_program_equiv</a> [lemma, in <a href="backend.Main.html">backend.Main</a>]<br/>
-<a href="backend.Constprop.html#transf_code">transf_code</a> [definition, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.CSE.html#transf_code">transf_code</a> [definition, in <a href="backend.CSE.html">backend.CSE</a>]<br/>
-<a href="backend.CSE.html#transf_code_wf">transf_code_wf</a> [lemma, in <a href="backend.CSE.html">backend.CSE</a>]<br/>
-<a href="backend.Constprop.html#transf_code_wf">transf_code_wf</a> [lemma, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.RTL.html#transf_code_wf">transf_code_wf</a> [lemma, in <a href="backend.RTL.html">backend.RTL</a>]<br/>
-<a href="backend.Main.html#transf_csharpminor_function">transf_csharpminor_function</a> [definition, in <a href="backend.Main.html">backend.Main</a>]<br/>
-<a href="backend.Main.html#transf_csharpminor_program">transf_csharpminor_program</a> [definition, in <a href="backend.Main.html">backend.Main</a>]<br/>
-<a href="backend.Main.html#transf_csharpminor_program2">transf_csharpminor_program2</a> [definition, in <a href="backend.Main.html">backend.Main</a>]<br/>
-<a href="backend.Main.html#transf_csharpminor_program2_correct">transf_csharpminor_program2_correct</a> [lemma, in <a href="backend.Main.html">backend.Main</a>]<br/>
-<a href="backend.Main.html#transf_csharpminor_program_correct">transf_csharpminor_program_correct</a> [lemma, in <a href="backend.Main.html">backend.Main</a>]<br/>
-<a href="backend.Main.html#transf_csharpminor_program_equiv">transf_csharpminor_program_equiv</a> [lemma, in <a href="backend.Main.html">backend.Main</a>]<br/>
-<a href="backend.Allocation.html#transf_entrypoint">transf_entrypoint</a> [definition, in <a href="backend.Allocation.html">backend.Allocation</a>]<br/>
-<a href="backend.Allocproof.html#transf_entrypoint_correct">transf_entrypoint_correct</a> [lemma, in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.Allocation.html#transf_entrypoint_wf">transf_entrypoint_wf</a> [lemma, in <a href="backend.Allocation.html">backend.Allocation</a>]<br/>
-<a href="backend.Linearize.html#transf_function">transf_function</a> [definition, in <a href="backend.Linearize.html">backend.Linearize</a>]<br/>
-<a href="backend.Allocation.html#transf_function">transf_function</a> [definition, in <a href="backend.Allocation.html">backend.Allocation</a>]<br/>
-<a href="backend.CSE.html#transf_function">transf_function</a> [definition, in <a href="backend.CSE.html">backend.CSE</a>]<br/>
-<a href="backend.RTL.html#transf_function">transf_function</a> [definition, in <a href="backend.RTL.html">backend.RTL</a>]<br/>
-<a href="backend.PPCgen.html#transf_function">transf_function</a> [definition, in <a href="backend.PPCgen.html">backend.PPCgen</a>]<br/>
-<a href="backend.Stacking.html#transf_function">transf_function</a> [definition, in <a href="backend.Stacking.html">backend.Stacking</a>]<br/>
-<a href="backend.Constprop.html#transf_function">transf_function</a> [definition, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Linearizeproof.html#transf_function_correct">transf_function_correct</a> [lemma, in <a href="backend.Linearizeproof.html">backend.Linearizeproof</a>]<br/>
-<a href="backend.PPCgenproof.html#transf_function_correct">transf_function_correct</a> [lemma, in <a href="backend.PPCgenproof.html">backend.PPCgenproof</a>]<br/>
-<a href="backend.Stackingproof.html#transf_function_correct">transf_function_correct</a> [lemma, in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="backend.CSEproof.html#transf_function_correct">transf_function_correct</a> [lemma, in <a href="backend.CSEproof.html">backend.CSEproof</a>]<br/>
-<a href="backend.Constpropproof.html#transf_funct_correct">transf_funct_correct</a> [lemma, in <a href="backend.Constpropproof.html">backend.Constpropproof</a>]<br/>
-<a href="backend.Allocation.html#transf_instr">transf_instr</a> [definition, in <a href="backend.Allocation.html">backend.Allocation</a>]<br/>
-<a href="backend.Constprop.html#transf_instr">transf_instr</a> [definition, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.CSE.html#transf_instr">transf_instr</a> [definition, in <a href="backend.CSE.html">backend.CSE</a>]<br/>
-<a href="backend.Globalenvs.html#transf_partial">transf_partial</a> [definition, in <a href="backend.Globalenvs.html">backend.Globalenvs</a>]<br/>
-<a href="backend.AST.html#transf_partial_program">transf_partial_program</a> [definition, in <a href="backend.AST.html">backend.AST</a>]<br/>
-<a href="backend.Main.html#transf_partial_program_compose">transf_partial_program_compose</a> [lemma, in <a href="backend.Main.html">backend.Main</a>]<br/>
-<a href="backend.CSE.html#transf_program">transf_program</a> [definition, in <a href="backend.CSE.html">backend.CSE</a>]<br/>
-<a href="backend.PPCgen.html#transf_program">transf_program</a> [definition, in <a href="backend.PPCgen.html">backend.PPCgen</a>]<br/>
-<a href="backend.Stacking.html#transf_program">transf_program</a> [definition, in <a href="backend.Stacking.html">backend.Stacking</a>]<br/>
-<a href="backend.Constprop.html#transf_program">transf_program</a> [definition, in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Allocation.html#transf_program">transf_program</a> [definition, in <a href="backend.Allocation.html">backend.Allocation</a>]<br/>
-<a href="backend.Linearize.html#transf_program">transf_program</a> [definition, in <a href="backend.Linearize.html">backend.Linearize</a>]<br/>
-<a href="backend.AST.html#transf_program">transf_program</a> [definition, in <a href="backend.AST.html">backend.AST</a>]<br/>
-<a href="backend.Linearizeproof.html#transf_program_correct">transf_program_correct</a> [lemma, in <a href="backend.Linearizeproof.html">backend.Linearizeproof</a>]<br/>
-<a href="backend.Tunnelingproof.html#transf_program_correct">transf_program_correct</a> [lemma, in <a href="backend.Tunnelingproof.html">backend.Tunnelingproof</a>]<br/>
-<a href="backend.Constpropproof.html#transf_program_correct">transf_program_correct</a> [lemma, in <a href="backend.Constpropproof.html">backend.Constpropproof</a>]<br/>
-<a href="backend.PPCgenproof.html#transf_program_correct">transf_program_correct</a> [lemma, in <a href="backend.PPCgenproof.html">backend.PPCgenproof</a>]<br/>
-<a href="backend.CSEproof.html#transf_program_correct">transf_program_correct</a> [lemma, in <a href="backend.CSEproof.html">backend.CSEproof</a>]<br/>
-<a href="backend.Main.html#transf_program_partial_total">transf_program_partial_total</a> [lemma, in <a href="backend.Main.html">backend.Main</a>]<br/>
-<a href="backend.Globalenvs.html#transf_program_transf_partial_program">transf_program_transf_partial_program</a> [lemma, in <a href="backend.Globalenvs.html">backend.Globalenvs</a>]<br/>
-<a href="lib.Integers.html#translate_cmp">translate_cmp</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#translate_eq">translate_eq</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#translate_lt">translate_lt</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Stacking.html#transl_addr">transl_addr</a> [definition, in <a href="backend.Stacking.html">backend.Stacking</a>]<br/>
-<a href="backend.Stacking.html#transl_body">transl_body</a> [definition, in <a href="backend.Stacking.html">backend.Stacking</a>]<br/>
-<a href="backend.PPCgen.html#transl_code">transl_code</a> [definition, in <a href="backend.PPCgen.html">backend.PPCgen</a>]<br/>
-<a href="backend.Stacking.html#transl_code">transl_code</a> [definition, in <a href="backend.Stacking.html">backend.Stacking</a>]<br/>
-<a href="backend.PPCgenproof.html#transl_code_at_pc">transl_code_at_pc</a> [inductive, in <a href="backend.PPCgenproof.html">backend.PPCgenproof</a>]<br/>
-<a href="backend.PPCgenproof.html#transl_code_label">transl_code_label</a> [lemma, in <a href="backend.PPCgenproof.html">backend.PPCgenproof</a>]<br/>
-<a href="backend.PPCgen.html#transl_cond">transl_cond</a> [definition, in <a href="backend.PPCgen.html">backend.PPCgen</a>]<br/>
-<a href="backend.RTLgenproof.html#transl_condition_CEcondition_correct">transl_condition_CEcondition_correct</a> [lemma, in <a href="backend.RTLgenproof.html">backend.RTLgenproof</a>]<br/>
-<a href="backend.RTLgenproof.html#transl_condition_CEcond_correct">transl_condition_CEcond_correct</a> [lemma, in <a href="backend.RTLgenproof.html">backend.RTLgenproof</a>]<br/>
-<a href="backend.RTLgenproof.html#transl_condition_CEfalse_correct">transl_condition_CEfalse_correct</a> [lemma, in <a href="backend.RTLgenproof.html">backend.RTLgenproof</a>]<br/>
-<a href="backend.RTLgenproof.html#transl_condition_CEtrue_correct">transl_condition_CEtrue_correct</a> [lemma, in <a href="backend.RTLgenproof.html">backend.RTLgenproof</a>]<br/>
-<a href="backend.RTLgenproof.html#transl_condition_correct">transl_condition_correct</a> [definition, in <a href="backend.RTLgenproof.html">backend.RTLgenproof</a>]<br/>
-<a href="backend.RTLgenproof1.html#transl_condition_incr">transl_condition_incr</a> [lemma, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#transl_condition_incr_pred">transl_condition_incr_pred</a> [definition, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.PPCgenproof1.html#transl_cond_correct">transl_cond_correct</a> [lemma, in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.PPCgenproof1.html#transl_cond_correct_aux">transl_cond_correct_aux</a> [lemma, in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.RTLgen.html#transl_expr">transl_expr</a> [definition, in <a href="backend.RTLgen.html">backend.RTLgen</a>]<br/>
-<a href="backend.Cminorgen.html#transl_expr">transl_expr</a> [definition, in <a href="backend.Cminorgen.html">backend.Cminorgen</a>]<br/>
-<a href="backend.RTLgenproof.html#transl_exprlist_correct">transl_exprlist_correct</a> [definition, in <a href="backend.RTLgenproof.html">backend.RTLgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#transl_exprlist_Econs_correct">transl_exprlist_Econs_correct</a> [lemma, in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.RTLgenproof.html#transl_exprlist_Econs_correct">transl_exprlist_Econs_correct</a> [lemma, in <a href="backend.RTLgenproof.html">backend.RTLgenproof</a>]<br/>
-<a href="backend.RTLgenproof.html#transl_exprlist_Enil_correct">transl_exprlist_Enil_correct</a> [lemma, in <a href="backend.RTLgenproof.html">backend.RTLgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#transl_exprlist_Enil_correct">transl_exprlist_Enil_correct</a> [lemma, in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.RTLgenproof1.html#transl_exprlist_incr">transl_exprlist_incr</a> [lemma, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#transl_exprlist_incr_pred">transl_exprlist_incr_pred</a> [definition, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#transl_expr_condition_exprlist_incr">transl_expr_condition_exprlist_incr</a> [lemma, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof.html#transl_expr_correct">transl_expr_correct</a> [definition, in <a href="backend.RTLgenproof.html">backend.RTLgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#transl_expr_Eaddrof_global_correct">transl_expr_Eaddrof_global_correct</a> [lemma, in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#transl_expr_Eaddrof_local_correct">transl_expr_Eaddrof_local_correct</a> [lemma, in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#transl_expr_Eassign_correct">transl_expr_Eassign_correct</a> [lemma, in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.RTLgenproof.html#transl_expr_Eassign_correct">transl_expr_Eassign_correct</a> [lemma, in <a href="backend.RTLgenproof.html">backend.RTLgenproof</a>]<br/>
-<a href="backend.RTLgenproof.html#transl_expr_Ecall_correct">transl_expr_Ecall_correct</a> [lemma, in <a href="backend.RTLgenproof.html">backend.RTLgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#transl_expr_Ecall_correct">transl_expr_Ecall_correct</a> [lemma, in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.RTLgenproof.html#transl_expr_Econdition_correct">transl_expr_Econdition_correct</a> [lemma, in <a href="backend.RTLgenproof.html">backend.RTLgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#transl_expr_Econdition_false_correct">transl_expr_Econdition_false_correct</a> [lemma, in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#transl_expr_Econdition_true_correct">transl_expr_Econdition_true_correct</a> [lemma, in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.RTLgenproof.html#transl_expr_Eletvar_correct">transl_expr_Eletvar_correct</a> [lemma, in <a href="backend.RTLgenproof.html">backend.RTLgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#transl_expr_Eletvar_correct">transl_expr_Eletvar_correct</a> [lemma, in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#transl_expr_Elet_correct">transl_expr_Elet_correct</a> [lemma, in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.RTLgenproof.html#transl_expr_Elet_correct">transl_expr_Elet_correct</a> [lemma, in <a href="backend.RTLgenproof.html">backend.RTLgenproof</a>]<br/>
-<a href="backend.RTLgenproof.html#transl_expr_Eload_correct">transl_expr_Eload_correct</a> [lemma, in <a href="backend.RTLgenproof.html">backend.RTLgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#transl_expr_Eload_correct">transl_expr_Eload_correct</a> [lemma, in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.RTLgenproof.html#transl_expr_Eop_correct">transl_expr_Eop_correct</a> [lemma, in <a href="backend.RTLgenproof.html">backend.RTLgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#transl_expr_Eop_correct">transl_expr_Eop_correct</a> [lemma, in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.RTLgenproof.html#transl_expr_Estore_correct">transl_expr_Estore_correct</a> [lemma, in <a href="backend.RTLgenproof.html">backend.RTLgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#transl_expr_Estore_correct">transl_expr_Estore_correct</a> [lemma, in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#transl_expr_Evar_correct">transl_expr_Evar_correct</a> [lemma, in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.RTLgenproof.html#transl_expr_Evar_correct">transl_expr_Evar_correct</a> [lemma, in <a href="backend.RTLgenproof.html">backend.RTLgenproof</a>]<br/>
-<a href="backend.RTLgenproof1.html#transl_expr_incr">transl_expr_incr</a> [lemma, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#transl_expr_incr_pred">transl_expr_incr_pred</a> [definition, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.PPCgenproof.html#transl_find_label">transl_find_label</a> [lemma, in <a href="backend.PPCgenproof.html">backend.PPCgenproof</a>]<br/>
-<a href="backend.Stackingproof.html#transl_find_label">transl_find_label</a> [lemma, in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="backend.RTLgen.html#transl_fun">transl_fun</a> [definition, in <a href="backend.RTLgen.html">backend.RTLgen</a>]<br/>
-<a href="backend.Cminorgenproof.html#transl_funcall_correct">transl_funcall_correct</a> [lemma, in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.RTLgenproof.html#transl_funcall_correct">transl_funcall_correct</a> [lemma, in <a href="backend.RTLgenproof.html">backend.RTLgenproof</a>]<br/>
-<a href="backend.Cminorgen.html#transl_function">transl_function</a> [definition, in <a href="backend.Cminorgen.html">backend.Cminorgen</a>]<br/>
-<a href="backend.PPCgen.html#transl_function">transl_function</a> [definition, in <a href="backend.PPCgen.html">backend.PPCgen</a>]<br/>
-<a href="backend.RTLgen.html#transl_function">transl_function</a> [definition, in <a href="backend.RTLgen.html">backend.RTLgen</a>]<br/>
-<a href="backend.RTLgenproof.html#transl_function_correct">transl_function_correct</a> [definition, in <a href="backend.RTLgenproof.html">backend.RTLgenproof</a>]<br/>
-<a href="backend.Allocproof.html#transl_function_correct">transl_function_correct</a> [lemma, in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#transl_function_correct">transl_function_correct</a> [lemma, in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Allocproof.html#transl_function_correctness">transl_function_correctness</a> [lemma, in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.RTLgenproof.html#transl_function_correctness">transl_function_correctness</a> [lemma, in <a href="backend.RTLgenproof.html">backend.RTLgenproof</a>]<br/>
-<a href="backend.Allocproof.html#transl_Icall_correct">transl_Icall_correct</a> [lemma, in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.Allocproof.html#transl_Icond_false_correct">transl_Icond_false_correct</a> [lemma, in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.Allocproof.html#transl_Icond_true_correct">transl_Icond_true_correct</a> [lemma, in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.Allocproof.html#transl_Iload_correct">transl_Iload_correct</a> [lemma, in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.Allocproof.html#transl_Inop_correct">transl_Inop_correct</a> [lemma, in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.PPCgen.html#transl_instr">transl_instr</a> [definition, in <a href="backend.PPCgen.html">backend.PPCgen</a>]<br/>
-<a href="backend.Stacking.html#transl_instr">transl_instr</a> [definition, in <a href="backend.Stacking.html">backend.Stacking</a>]<br/>
-<a href="backend.PPCgenproof.html#transl_instr_label">transl_instr_label</a> [lemma, in <a href="backend.PPCgenproof.html">backend.PPCgenproof</a>]<br/>
-<a href="backend.Allocproof.html#transl_Iop_correct">transl_Iop_correct</a> [lemma, in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.Allocproof.html#transl_Istore_correct">transl_Istore_correct</a> [lemma, in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.PPCgenproof1.html#transl_load_correct">transl_load_correct</a> [lemma, in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.PPCgen.html#transl_load_store">transl_load_store</a> [definition, in <a href="backend.PPCgen.html">backend.PPCgen</a>]<br/>
-<a href="backend.PPCgenproof1.html#transl_load_store_correct">transl_load_store_correct</a> [lemma, in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.Allocproof.html#transl_one_correct">transl_one_correct</a> [lemma, in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.Stacking.html#transl_op">transl_op</a> [definition, in <a href="backend.Stacking.html">backend.Stacking</a>]<br/>
-<a href="backend.PPCgen.html#transl_op">transl_op</a> [definition, in <a href="backend.PPCgen.html">backend.PPCgen</a>]<br/>
-<a href="backend.PPCgenproof1.html#transl_op_correct">transl_op_correct</a> [lemma, in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.RTLgen.html#transl_program">transl_program</a> [definition, in <a href="backend.RTLgen.html">backend.RTLgen</a>]<br/>
-<a href="backend.Cminorgen.html#transl_program">transl_program</a> [definition, in <a href="backend.Cminorgen.html">backend.Cminorgen</a>]<br/>
-<a href="backend.RTLgenproof.html#transl_program_correct">transl_program_correct</a> [lemma, in <a href="backend.RTLgenproof.html">backend.RTLgenproof</a>]<br/>
-<a href="backend.Stackingproof.html#transl_program_correct">transl_program_correct</a> [lemma, in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="backend.Allocproof.html#transl_program_correct">transl_program_correct</a> [lemma, in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#transl_program_correct">transl_program_correct</a> [lemma, in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Allocproof.html#transl_refl_correct">transl_refl_correct</a> [lemma, in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.Cminorgen.html#transl_stmt">transl_stmt</a> [definition, in <a href="backend.Cminorgen.html">backend.Cminorgen</a>]<br/>
-<a href="backend.RTLgen.html#transl_stmt">transl_stmt</a> [definition, in <a href="backend.RTLgen.html">backend.RTLgen</a>]<br/>
-<a href="backend.RTLgenproof.html#transl_stmtlist_correct">transl_stmtlist_correct</a> [definition, in <a href="backend.RTLgenproof.html">backend.RTLgenproof</a>]<br/>
-<a href="backend.RTLgenproof1.html#transl_stmtlist_incr">transl_stmtlist_incr</a> [lemma, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#transl_stmtlist_incr_pred">transl_stmtlist_incr_pred</a> [definition, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof.html#transl_stmtlist_Scons_continue_correct">transl_stmtlist_Scons_continue_correct</a> [lemma, in <a href="backend.RTLgenproof.html">backend.RTLgenproof</a>]<br/>
-<a href="backend.RTLgenproof.html#transl_stmtlist_Scons_stop_correct">transl_stmtlist_Scons_stop_correct</a> [lemma, in <a href="backend.RTLgenproof.html">backend.RTLgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#transl_stmtlist_Scons_1_correct">transl_stmtlist_Scons_1_correct</a> [lemma, in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#transl_stmtlist_Scons_2_correct">transl_stmtlist_Scons_2_correct</a> [lemma, in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.RTLgenproof.html#transl_stmtlist_Snil_correct">transl_stmtlist_Snil_correct</a> [lemma, in <a href="backend.RTLgenproof.html">backend.RTLgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#transl_stmtlist_Snil_correct">transl_stmtlist_Snil_correct</a> [lemma, in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.RTLgenproof.html#transl_stmt_correct">transl_stmt_correct</a> [definition, in <a href="backend.RTLgenproof.html">backend.RTLgenproof</a>]<br/>
-<a href="backend.RTLgenproof1.html#transl_stmt_incr">transl_stmt_incr</a> [lemma, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#transl_stmt_incr_pred">transl_stmt_incr_pred</a> [definition, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof.html#transl_stmt_Sblock_correct">transl_stmt_Sblock_correct</a> [lemma, in <a href="backend.RTLgenproof.html">backend.RTLgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#transl_stmt_Sblock_correct">transl_stmt_Sblock_correct</a> [lemma, in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.RTLgenproof.html#transl_stmt_Sexit_correct">transl_stmt_Sexit_correct</a> [lemma, in <a href="backend.RTLgenproof.html">backend.RTLgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#transl_stmt_Sexit_correct">transl_stmt_Sexit_correct</a> [lemma, in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.RTLgenproof.html#transl_stmt_Sexpr_correct">transl_stmt_Sexpr_correct</a> [lemma, in <a href="backend.RTLgenproof.html">backend.RTLgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#transl_stmt_Sexpr_correct">transl_stmt_Sexpr_correct</a> [lemma, in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.RTLgenproof.html#transl_stmt_Sifthenelse_correct">transl_stmt_Sifthenelse_correct</a> [lemma, in <a href="backend.RTLgenproof.html">backend.RTLgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#transl_stmt_Sifthenelse_false_correct">transl_stmt_Sifthenelse_false_correct</a> [lemma, in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#transl_stmt_Sifthenelse_true_correct">transl_stmt_Sifthenelse_true_correct</a> [lemma, in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#transl_stmt_Sloop_exit_correct">transl_stmt_Sloop_exit_correct</a> [lemma, in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#transl_stmt_Sloop_loop_correct">transl_stmt_Sloop_loop_correct</a> [lemma, in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.RTLgenproof.html#transl_stmt_Sloop_loop_correct">transl_stmt_Sloop_loop_correct</a> [lemma, in <a href="backend.RTLgenproof.html">backend.RTLgenproof</a>]<br/>
-<a href="backend.RTLgenproof.html#transl_stmt_Sloop_stop_correct">transl_stmt_Sloop_stop_correct</a> [lemma, in <a href="backend.RTLgenproof.html">backend.RTLgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#transl_stmt_Sreturn_none_correct">transl_stmt_Sreturn_none_correct</a> [lemma, in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.RTLgenproof.html#transl_stmt_Sreturn_none_correct">transl_stmt_Sreturn_none_correct</a> [lemma, in <a href="backend.RTLgenproof.html">backend.RTLgenproof</a>]<br/>
-<a href="backend.RTLgenproof.html#transl_stmt_Sreturn_some_correct">transl_stmt_Sreturn_some_correct</a> [lemma, in <a href="backend.RTLgenproof.html">backend.RTLgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#transl_stmt_Sreturn_some_correct">transl_stmt_Sreturn_some_correct</a> [lemma, in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.RTLgenproof1.html#transl_stmt_stmtlist_incr">transl_stmt_stmtlist_incr</a> [lemma, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.PPCgenproof1.html#transl_store_correct">transl_store_correct</a> [lemma, in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.Allocproof.html#transl_trans_correct">transl_trans_correct</a> [lemma, in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="lib.Maps.html#tree">tree</a> [inductive, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#TREE">TREE</a> [module, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="backend.RTLtyping.html#tReg">tReg</a> [constructor, in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.RTLtyping.html#tTy">tTy</a> [constructor, in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.Tunnelingproof.html#tunneled_code">tunneled_code</a> [definition, in <a href="backend.Tunnelingproof.html">backend.Tunnelingproof</a>]<br/>
-<a href="backend.Tunneling.html">Tunneling</a> [library]<br/>
-<a href="backend.Tunnelingproof.html">Tunnelingproof</a> [library]<br/>
-<a href="backend.Tunnelingtyping.html">Tunnelingtyping</a> [library]<br/>
-<a href="backend.Tunneling.html#tunnel_block">tunnel_block</a> [definition, in <a href="backend.Tunneling.html">backend.Tunneling</a>]<br/>
-<a href="backend.Tunneling.html#tunnel_function">tunnel_function</a> [definition, in <a href="backend.Tunneling.html">backend.Tunneling</a>]<br/>
-<a href="backend.Tunnelingproof.html#tunnel_function_correct">tunnel_function_correct</a> [lemma, in <a href="backend.Tunnelingproof.html">backend.Tunnelingproof</a>]<br/>
-<a href="backend.Tunnelingproof.html#tunnel_outcome">tunnel_outcome</a> [definition, in <a href="backend.Tunnelingproof.html">backend.Tunnelingproof</a>]<br/>
-<a href="backend.Tunneling.html#tunnel_program">tunnel_program</a> [definition, in <a href="backend.Tunneling.html">backend.Tunneling</a>]<br/>
-<a href="lib.Coqlib.html#two_power_nat_O">two_power_nat_O</a> [lemma, in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#two_power_nat_pos">two_power_nat_pos</a> [lemma, in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="backend.AST.html#typ">typ</a> [inductive, in <a href="backend.AST.html">backend.AST</a>]<br/>
-<a href="backend.Locations.html#type">type</a> [definition, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Registers.html#typenv">typenv</a> [definition, in <a href="backend.Registers.html">backend.Registers</a>]<br/>
-<a href="backend.AST.html#typesize">typesize</a> [definition, in <a href="backend.AST.html">backend.AST</a>]<br/>
-<a href="backend.Locations.html#typesize">typesize</a> [definition, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#typesize_pos">typesize_pos</a> [lemma, in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.RTLtyping.html#type_args_complete">type_args_complete</a> [lemma, in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.RTLtyping.html#type_args_correct">type_args_correct</a> [lemma, in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.RTLtyping.html#type_args_extends">type_args_extends</a> [lemma, in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.RTLtyping.html#type_args_included">type_args_included</a> [lemma, in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.RTLtyping.html#type_args_mapped">type_args_mapped</a> [lemma, in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.RTLtyping.html#type_args_res_complete">type_args_res_complete</a> [lemma, in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.RTLtyping.html#type_args_res_included">type_args_res_included</a> [lemma, in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.RTLtyping.html#type_args_res_ros_included">type_args_res_ros_included</a> [lemma, in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.RTLtyping.html#type_arg_complete">type_arg_complete</a> [lemma, in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.RTLtyping.html#type_arg_correct">type_arg_correct</a> [lemma, in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.RTLtyping.html#type_arg_correct_1">type_arg_correct_1</a> [lemma, in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.RTLtyping.html#type_arg_extends">type_arg_extends</a> [lemma, in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.RTLtyping.html#type_arg_included">type_arg_included</a> [lemma, in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.RTLtyping.html#type_arg_mapped">type_arg_mapped</a> [lemma, in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.RTLtyping.html#type_instrs_extends">type_instrs_extends</a> [lemma, in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.RTLtyping.html#type_instrs_included">type_instrs_included</a> [lemma, in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.RTLtyping.html#type_instr_included">type_instr_included</a> [lemma, in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.Op.html#type_of_addressing">type_of_addressing</a> [definition, in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Op.html#type_of_chunk">type_of_chunk</a> [definition, in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Op.html#type_of_chunk_correct">type_of_chunk_correct</a> [lemma, in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Op.html#type_of_condition">type_of_condition</a> [definition, in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Stackingproof.html#type_of_index">type_of_index</a> [definition, in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="backend.Op.html#type_of_operation">type_of_operation</a> [definition, in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Op.html#type_of_operation_sound">type_of_operation_sound</a> [lemma, in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.RTLtyping.html#type_of_sig_res">type_of_sig_res</a> [definition, in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.RTLtyping.html#type_res_complete">type_res_complete</a> [lemma, in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.RTLtyping.html#type_res_correct">type_res_correct</a> [lemma, in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.RTLtyping.html#type_ros_complete">type_ros_complete</a> [lemma, in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.RTLtyping.html#type_ros_correct">type_ros_correct</a> [lemma, in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.RTLtyping.html#type_rtl_arg">type_rtl_arg</a> [definition, in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.RTLtyping.html#type_rtl_function">type_rtl_function</a> [definition, in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.RTLtyping.html#type_rtl_function_correct">type_rtl_function_correct</a> [lemma, in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.RTLtyping.html#type_rtl_function_instrs">type_rtl_function_instrs</a> [lemma, in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.RTLtyping.html#type_rtl_function_norepet">type_rtl_function_norepet</a> [lemma, in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.RTLtyping.html#type_rtl_function_params">type_rtl_function_params</a> [lemma, in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.RTLtyping.html#type_rtl_instr">type_rtl_instr</a> [definition, in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.RTLtyping.html#type_rtl_ros">type_rtl_ros</a> [definition, in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="lib.Lattice.html#t_">t_</a> [inductive, in <a href="lib.Lattice.html">lib.Lattice</a>]<br/>
-<a href="lib.Lattice.html#t_">t_</a> [inductive, in <a href="lib.Lattice.html">lib.Lattice</a>]<br/>
-<a href="backend.Alloctyping_aux.html#T_type">T_type</a> [lemma, in <a href="backend.Alloctyping_aux.html">backend.Alloctyping_aux</a>]<br/>
-<br/><br/><a name="global_U"></a><h2>U </h2>
-<a href="backend.RTLtyping.html#Uf">Uf</a> [module, in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.Mem.html#unchecked_store">unchecked_store</a> [definition, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#Undef">Undef</a> [constructor, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Values.html#undef_is_bool">undef_is_bool</a> [lemma, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Stackingproof.html#unfold_transf_function">unfold_transf_function</a> [lemma, in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="lib.Sets.html#union">union</a> [definition, in <a href="lib.Sets.html">lib.Sets</a>]<br/>
-<a href="lib.union_find.html#UNIONFIND">UNIONFIND</a> [module, in <a href="lib.union_find.html">lib.union_find</a>]<br/>
-<a href="lib.union_find.html#unionfind">unionfind</a> [inductive, in <a href="lib.union_find.html">lib.union_find</a>]<br/>
-<a href="lib.union_find.html#Unionfind">Unionfind</a> [module, in <a href="lib.union_find.html">lib.union_find</a>]<br/>
-<a href="lib.union_find.html">union_find</a> [library]<br/>
-<a href="backend.Linearizeproof.html#unique_labels">unique_labels</a> [definition, in <a href="backend.Linearizeproof.html">backend.Linearizeproof</a>]<br/>
-<a href="backend.Linearizeproof.html#unique_labels_lin_block">unique_labels_lin_block</a> [lemma, in <a href="backend.Linearizeproof.html">backend.Linearizeproof</a>]<br/>
-<a href="backend.Linearizeproof.html#unique_labels_lin_function">unique_labels_lin_function</a> [lemma, in <a href="backend.Linearizeproof.html">backend.Linearizeproof</a>]<br/>
-<a href="backend.Linearizeproof.html#unique_labels_lin_rec">unique_labels_lin_rec</a> [lemma, in <a href="backend.Linearizeproof.html">backend.Linearizeproof</a>]<br/>
-<a href="lib.Coqlib.html#unroll_positive_rec">unroll_positive_rec</a> [lemma, in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Integers.html#unsigned">unsigned</a> [definition, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#unsigned_range">unsigned_range</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#unsigned_range_2">unsigned_range_2</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#unsigned_repr">unsigned_repr</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Parallelmove.html#unsplit_move">unsplit_move</a> [lemma, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Mem.html#update">update</a> [definition, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Parallelmove.html#update">update</a> [definition, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.RTLgen.html#update_instr">update_instr</a> [definition, in <a href="backend.RTLgen.html">backend.RTLgen</a>]<br/>
-<a href="backend.RTLgenproof1.html#update_instr_extends">update_instr_extends</a> [lemma, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#update_instr_incr">update_instr_incr</a> [lemma, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgen.html#update_instr_wf">update_instr_wf</a> [lemma, in <a href="backend.RTLgen.html">backend.RTLgen</a>]<br/>
-<a href="backend.Mem.html#update_o">update_o</a> [lemma, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#update_s">update_s</a> [lemma, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<br/><br/><a name="global_V"></a><h2>V </h2>
-<a href="backend.Values.html#Val">Val</a> [module, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Values.html#val">val</a> [inductive, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Mem.html#valid_block">valid_block</a> [definition, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#valid_block_alloc">valid_block_alloc</a> [lemma, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#valid_block_free">valid_block_free</a> [lemma, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#valid_block_store">valid_block_store</a> [lemma, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.RTLgenproof1.html#valid_fresh_absurd">valid_fresh_absurd</a> [lemma, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#valid_fresh_different">valid_fresh_different</a> [lemma, in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.Mem.html#valid_new_block">valid_new_block</a> [lemma, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#valid_not_valid_diff">valid_not_valid_diff</a> [lemma, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Linearizeproof.html#valid_outcome">valid_outcome</a> [definition, in <a href="backend.Linearizeproof.html">backend.Linearizeproof</a>]<br/>
-<a href="backend.Mem.html#valid_pointer">valid_pointer</a> [definition, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#valid_pointer_inject_no_overflow">valid_pointer_inject_no_overflow</a> [lemma, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.CSE.html#valnum">valnum</a> [definition, in <a href="backend.CSE.html">backend.CSE</a>]<br/>
-<a href="backend.CSEproof.html#ValnumEq">ValnumEq</a> [module, in <a href="backend.CSEproof.html">backend.CSEproof</a>]<br/>
-<a href="backend.CSE.html#valnum_reg">valnum_reg</a> [definition, in <a href="backend.CSE.html">backend.CSE</a>]<br/>
-<a href="backend.CSE.html#valnum_regs">valnum_regs</a> [definition, in <a href="backend.CSE.html">backend.CSE</a>]<br/>
-<a href="backend.CSEproof.html#valnum_regs_holds">valnum_regs_holds</a> [lemma, in <a href="backend.CSEproof.html">backend.CSEproof</a>]<br/>
-<a href="backend.CSEproof.html#valnum_reg_holds">valnum_reg_holds</a> [lemma, in <a href="backend.CSEproof.html">backend.CSEproof</a>]<br/>
-<a href="backend.Parallelmove.html#Value">Value</a> [definition, in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Values.html">Values</a> [library]<br/>
-<a href="backend.CSEproof.html#valu_agree">valu_agree</a> [definition, in <a href="backend.CSEproof.html">backend.CSEproof</a>]<br/>
-<a href="backend.CSEproof.html#valu_agree_list">valu_agree_list</a> [lemma, in <a href="backend.CSEproof.html">backend.CSEproof</a>]<br/>
-<a href="backend.CSEproof.html#valu_agree_refl">valu_agree_refl</a> [lemma, in <a href="backend.CSEproof.html">backend.CSEproof</a>]<br/>
-<a href="backend.CSEproof.html#valu_agree_trans">valu_agree_trans</a> [lemma, in <a href="backend.CSEproof.html">backend.CSEproof</a>]<br/>
-<a href="backend.PPC.html#val_cond_reg">val_cond_reg</a> [definition, in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.Mem.html#val_cons_inject">val_cons_inject</a> [constructor, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#val_content_inject">val_content_inject</a> [inductive, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#val_content_inject_base">val_content_inject_base</a> [constructor, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Cminorgenproof.html#val_content_inject_cast">val_content_inject_cast</a> [lemma, in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Mem.html#val_content_inject_incr">val_content_inject_incr</a> [lemma, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#val_content_inject_8">val_content_inject_8</a> [constructor, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#val_inject">val_inject</a> [inductive, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#val_inject_float">val_inject_float</a> [constructor, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#val_inject_incr">val_inject_incr</a> [lemma, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#val_inject_int">val_inject_int</a> [constructor, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#val_inject_ptr">val_inject_ptr</a> [constructor, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#val_list_inject">val_list_inject</a> [inductive, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#val_list_inject_incr">val_list_inject_incr</a> [lemma, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Constpropproof.html#val_list_match_approx">val_list_match_approx</a> [inductive, in <a href="backend.Constpropproof.html">backend.Constpropproof</a>]<br/>
-<a href="backend.Constpropproof.html#val_match_approx">val_match_approx</a> [definition, in <a href="backend.Constpropproof.html">backend.Constpropproof</a>]<br/>
-<a href="backend.Constpropproof.html#val_match_approx_increasing">val_match_approx_increasing</a> [lemma, in <a href="backend.Constpropproof.html">backend.Constpropproof</a>]<br/>
-<a href="backend.Mem.html#val_nil_inject">val_nil_inject</a> [constructor, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Cminorgenproof.html#val_normalized">val_normalized</a> [definition, in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#vars_vals_cons">vars_vals_cons</a> [constructor, in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#vars_vals_match">vars_vals_match</a> [inductive, in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#vars_vals_match_extensional">vars_vals_match_extensional</a> [lemma, in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#vars_vals_match_holds">vars_vals_match_holds</a> [lemma, in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#vars_vals_match_holds_1">vars_vals_match_holds_1</a> [lemma, in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#vars_vals_nil">vars_vals_nil</a> [constructor, in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Cminorgen.html#var_addr">var_addr</a> [definition, in <a href="backend.Cminorgen.html">backend.Cminorgen</a>]<br/>
-<a href="backend.Cminorgenproof.html#var_addr_global_correct">var_addr_global_correct</a> [lemma, in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#var_addr_local_correct">var_addr_local_correct</a> [lemma, in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Cminorgen.html#var_get">var_get</a> [definition, in <a href="backend.Cminorgen.html">backend.Cminorgen</a>]<br/>
-<a href="backend.Cminorgenproof.html#var_get_correct">var_get_correct</a> [lemma, in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Cminorgen.html#Var_global">Var_global</a> [constructor, in <a href="backend.Cminorgen.html">backend.Cminorgen</a>]<br/>
-<a href="backend.Cminorgen.html#var_info">var_info</a> [inductive, in <a href="backend.Cminorgen.html">backend.Cminorgen</a>]<br/>
-<a href="backend.Cminorgen.html#Var_local">Var_local</a> [constructor, in <a href="backend.Cminorgen.html">backend.Cminorgen</a>]<br/>
-<a href="backend.Cminorgen.html#var_set">var_set</a> [definition, in <a href="backend.Cminorgen.html">backend.Cminorgen</a>]<br/>
-<a href="backend.Cminorgenproof.html#var_set_correct">var_set_correct</a> [lemma, in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Cminorgen.html#Var_stack_array">Var_stack_array</a> [constructor, in <a href="backend.Cminorgen.html">backend.Cminorgen</a>]<br/>
-<a href="backend.Cminorgen.html#Var_stack_scalar">Var_stack_scalar</a> [constructor, in <a href="backend.Cminorgen.html">backend.Cminorgen</a>]<br/>
-<a href="backend.Values.html#Vfalse">Vfalse</a> [definition, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Values.html#Vfloat">Vfloat</a> [constructor, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Values.html#Vint">Vint</a> [constructor, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Constpropproof.html#vlma_cons">vlma_cons</a> [constructor, in <a href="backend.Constpropproof.html">backend.Constpropproof</a>]<br/>
-<a href="backend.Constpropproof.html#vlma_nil">vlma_nil</a> [constructor, in <a href="backend.Constpropproof.html">backend.Constpropproof</a>]<br/>
-<a href="backend.CSEproof.html#VMap">VMap</a> [module, in <a href="backend.CSEproof.html">backend.CSEproof</a>]<br/>
-<a href="backend.Values.html#Vmone">Vmone</a> [definition, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Values.html#Vone">Vone</a> [definition, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Values.html#Vptr">Vptr</a> [constructor, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Values.html#Vtrue">Vtrue</a> [definition, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Values.html#Vundef">Vundef</a> [constructor, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Values.html#Vzero">Vzero</a> [definition, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<br/><br/><a name="global_W"></a><h2>W </h2>
-<a href="backend.CSEproof.html#wf_add_load">wf_add_load</a> [lemma, in <a href="backend.CSEproof.html">backend.CSEproof</a>]<br/>
-<a href="backend.CSEproof.html#wf_add_op">wf_add_op</a> [lemma, in <a href="backend.CSEproof.html">backend.CSEproof</a>]<br/>
-<a href="backend.CSEproof.html#wf_add_rhs">wf_add_rhs</a> [lemma, in <a href="backend.CSEproof.html">backend.CSEproof</a>]<br/>
-<a href="backend.CSEproof.html#wf_analyze">wf_analyze</a> [lemma, in <a href="backend.CSEproof.html">backend.CSEproof</a>]<br/>
-<a href="lib.union_find.html#wf_empty">wf_empty</a> [lemma, in <a href="lib.union_find.html">lib.union_find</a>]<br/>
-<a href="backend.CSEproof.html#wf_empty_numbering">wf_empty_numbering</a> [lemma, in <a href="backend.CSEproof.html">backend.CSEproof</a>]<br/>
-<a href="backend.CSEproof.html#wf_equation">wf_equation</a> [definition, in <a href="backend.CSEproof.html">backend.CSEproof</a>]<br/>
-<a href="backend.CSEproof.html#wf_equation_increasing">wf_equation_increasing</a> [lemma, in <a href="backend.CSEproof.html">backend.CSEproof</a>]<br/>
-<a href="backend.CSEproof.html#wf_kill_loads">wf_kill_loads</a> [lemma, in <a href="backend.CSEproof.html">backend.CSEproof</a>]<br/>
-<a href="backend.CSEproof.html#wf_numbering">wf_numbering</a> [definition, in <a href="backend.CSEproof.html">backend.CSEproof</a>]<br/>
-<a href="backend.CSEproof.html#wf_rhs">wf_rhs</a> [definition, in <a href="backend.CSEproof.html">backend.CSEproof</a>]<br/>
-<a href="backend.CSEproof.html#wf_rhs_increasing">wf_rhs_increasing</a> [lemma, in <a href="backend.CSEproof.html">backend.CSEproof</a>]<br/>
-<a href="backend.CSEproof.html#wf_transfer">wf_transfer</a> [lemma, in <a href="backend.CSEproof.html">backend.CSEproof</a>]<br/>
-<a href="backend.Tunneling.html#wf_tunneled_code">wf_tunneled_code</a> [lemma, in <a href="backend.Tunneling.html">backend.Tunneling</a>]<br/>
-<a href="backend.CSEproof.html#wf_valnum_reg">wf_valnum_reg</a> [lemma, in <a href="backend.CSEproof.html">backend.CSEproof</a>]<br/>
-<a href="backend.CSEproof.html#wf_valnum_regs">wf_valnum_regs</a> [lemma, in <a href="backend.CSEproof.html">backend.CSEproof</a>]<br/>
-<a href="lib.Integers.html#wordsize">wordsize</a> [definition, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Alloctyping.html#wt_add_call">wt_add_call</a> [lemma, in <a href="backend.Alloctyping.html">backend.Alloctyping</a>]<br/>
-<a href="backend.Alloctyping.html#wt_add_cond">wt_add_cond</a> [lemma, in <a href="backend.Alloctyping.html">backend.Alloctyping</a>]<br/>
-<a href="backend.Alloctyping.html#wt_add_entry">wt_add_entry</a> [lemma, in <a href="backend.Alloctyping.html">backend.Alloctyping</a>]<br/>
-<a href="backend.Alloctyping.html#wt_add_load">wt_add_load</a> [lemma, in <a href="backend.Alloctyping.html">backend.Alloctyping</a>]<br/>
-<a href="backend.Alloctyping.html#wt_add_move">wt_add_move</a> [lemma, in <a href="backend.Alloctyping.html">backend.Alloctyping</a>]<br/>
-<a href="backend.Alloctyping_aux.html#wt_add_moves">wt_add_moves</a> [lemma, in <a href="backend.Alloctyping_aux.html">backend.Alloctyping_aux</a>]<br/>
-<a href="backend.Alloctyping.html#wt_add_op_move">wt_add_op_move</a> [lemma, in <a href="backend.Alloctyping.html">backend.Alloctyping</a>]<br/>
-<a href="backend.Alloctyping.html#wt_add_op_others">wt_add_op_others</a> [lemma, in <a href="backend.Alloctyping.html">backend.Alloctyping</a>]<br/>
-<a href="backend.Alloctyping.html#wt_add_op_undef">wt_add_op_undef</a> [lemma, in <a href="backend.Alloctyping.html">backend.Alloctyping</a>]<br/>
-<a href="backend.Alloctyping.html#wt_add_reload">wt_add_reload</a> [lemma, in <a href="backend.Alloctyping.html">backend.Alloctyping</a>]<br/>
-<a href="backend.Alloctyping.html#wt_add_reloads">wt_add_reloads</a> [lemma, in <a href="backend.Alloctyping.html">backend.Alloctyping</a>]<br/>
-<a href="backend.Alloctyping.html#wt_add_return">wt_add_return</a> [lemma, in <a href="backend.Alloctyping.html">backend.Alloctyping</a>]<br/>
-<a href="backend.Alloctyping.html#wt_add_spill">wt_add_spill</a> [lemma, in <a href="backend.Alloctyping.html">backend.Alloctyping</a>]<br/>
-<a href="backend.Alloctyping.html#wt_add_store">wt_add_store</a> [lemma, in <a href="backend.Alloctyping.html">backend.Alloctyping</a>]<br/>
-<a href="backend.Alloctyping.html#wt_add_undefs">wt_add_undefs</a> [lemma, in <a href="backend.Alloctyping.html">backend.Alloctyping</a>]<br/>
-<a href="backend.LTLtyping.html#wt_Bgetstack">wt_Bgetstack</a> [constructor, in <a href="backend.LTLtyping.html">backend.LTLtyping</a>]<br/>
-<a href="backend.LTLtyping.html#wt_block">wt_block</a> [inductive, in <a href="backend.LTLtyping.html">backend.LTLtyping</a>]<br/>
-<a href="backend.LTLtyping.html#wt_Bop">wt_Bop</a> [constructor, in <a href="backend.LTLtyping.html">backend.LTLtyping</a>]<br/>
-<a href="backend.LTLtyping.html#wt_Bopmove">wt_Bopmove</a> [constructor, in <a href="backend.LTLtyping.html">backend.LTLtyping</a>]<br/>
-<a href="backend.LTLtyping.html#wt_Bopundef">wt_Bopundef</a> [constructor, in <a href="backend.LTLtyping.html">backend.LTLtyping</a>]<br/>
-<a href="backend.LTLtyping.html#wt_Bsetstack">wt_Bsetstack</a> [constructor, in <a href="backend.LTLtyping.html">backend.LTLtyping</a>]<br/>
-<a href="backend.Machtyping.html#wt_content">wt_content</a> [definition, in <a href="backend.Machtyping.html">backend.Machtyping</a>]<br/>
-<a href="backend.Stackingtyping.html#wt_fold_right">wt_fold_right</a> [lemma, in <a href="backend.Stackingtyping.html">backend.Stackingtyping</a>]<br/>
-<a href="backend.Machtyping.html#wt_frame">wt_frame</a> [definition, in <a href="backend.Machtyping.html">backend.Machtyping</a>]<br/>
-<a href="backend.RTLtyping.html#wt_function">wt_function</a> [inductive, in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.Machtyping.html#wt_function">wt_function</a> [inductive, in <a href="backend.Machtyping.html">backend.Machtyping</a>]<br/>
-<a href="backend.LTLtyping.html#wt_function">wt_function</a> [definition, in <a href="backend.LTLtyping.html">backend.LTLtyping</a>]<br/>
-<a href="backend.Lineartyping.html#wt_function">wt_function</a> [definition, in <a href="backend.Lineartyping.html">backend.Lineartyping</a>]<br/>
-<a href="backend.Machtyping.html#wt_get_slot">wt_get_slot</a> [lemma, in <a href="backend.Machtyping.html">backend.Machtyping</a>]<br/>
-<a href="backend.Machtyping.html#wt_init_frame">wt_init_frame</a> [lemma, in <a href="backend.Machtyping.html">backend.Machtyping</a>]<br/>
-<a href="backend.RTLtyping.html#wt_init_regs">wt_init_regs</a> [lemma, in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.RTLtyping.html#wt_Inop">wt_Inop</a> [constructor, in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.Lineartyping.html#wt_instr">wt_instr</a> [inductive, in <a href="backend.Lineartyping.html">backend.Lineartyping</a>]<br/>
-<a href="backend.Machtyping.html#wt_instr">wt_instr</a> [inductive, in <a href="backend.Machtyping.html">backend.Machtyping</a>]<br/>
-<a href="backend.RTLtyping.html#wt_instr">wt_instr</a> [inductive, in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.Stackingtyping.html#wt_instrs">wt_instrs</a> [definition, in <a href="backend.Stackingtyping.html">backend.Stackingtyping</a>]<br/>
-<a href="backend.Stackingtyping.html#wt_instrs_cons">wt_instrs_cons</a> [lemma, in <a href="backend.Stackingtyping.html">backend.Stackingtyping</a>]<br/>
-<a href="backend.RTLtyping.html#wt_Iop">wt_Iop</a> [constructor, in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.RTLtyping.html#wt_Iopmove">wt_Iopmove</a> [constructor, in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.RTLtyping.html#wt_Iopundef">wt_Iopundef</a> [constructor, in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.Lineartyping.html#wt_Lgetstack">wt_Lgetstack</a> [constructor, in <a href="backend.Lineartyping.html">backend.Lineartyping</a>]<br/>
-<a href="backend.Linearizetyping.html#wt_linearize_block">wt_linearize_block</a> [lemma, in <a href="backend.Linearizetyping.html">backend.Linearizetyping</a>]<br/>
-<a href="backend.Linearizetyping.html#wt_linearize_body">wt_linearize_body</a> [lemma, in <a href="backend.Linearizetyping.html">backend.Linearizetyping</a>]<br/>
-<a href="backend.Lineartyping.html#wt_Lop">wt_Lop</a> [constructor, in <a href="backend.Lineartyping.html">backend.Lineartyping</a>]<br/>
-<a href="backend.Lineartyping.html#wt_Lopmove">wt_Lopmove</a> [constructor, in <a href="backend.Lineartyping.html">backend.Lineartyping</a>]<br/>
-<a href="backend.Lineartyping.html#wt_Lopundef">wt_Lopundef</a> [constructor, in <a href="backend.Lineartyping.html">backend.Lineartyping</a>]<br/>
-<a href="backend.Lineartyping.html#wt_Lsetstack">wt_Lsetstack</a> [constructor, in <a href="backend.Lineartyping.html">backend.Lineartyping</a>]<br/>
-<a href="backend.Machtyping.html#wt_Mgetstack">wt_Mgetstack</a> [constructor, in <a href="backend.Machtyping.html">backend.Machtyping</a>]<br/>
-<a href="backend.Machtyping.html#wt_Mlabel">wt_Mlabel</a> [constructor, in <a href="backend.Machtyping.html">backend.Machtyping</a>]<br/>
-<a href="backend.Machtyping.html#wt_Msetstack">wt_Msetstack</a> [constructor, in <a href="backend.Machtyping.html">backend.Machtyping</a>]<br/>
-<a href="backend.Stackingtyping.html#wt_Msetstack'">wt_Msetstack'</a> [lemma, in <a href="backend.Stackingtyping.html">backend.Stackingtyping</a>]<br/>
-<a href="backend.Alloctyping.html#wt_parallel_move">wt_parallel_move</a> [lemma, in <a href="backend.Alloctyping.html">backend.Alloctyping</a>]<br/>
-<a href="backend.Alloctyping_aux.html#wt_parallel_moveX">wt_parallel_moveX</a> [lemma, in <a href="backend.Alloctyping_aux.html">backend.Alloctyping_aux</a>]<br/>
-<a href="backend.Alloctyping_aux.html#wt_parallel_move'">wt_parallel_move'</a> [lemma, in <a href="backend.Alloctyping_aux.html">backend.Alloctyping_aux</a>]<br/>
-<a href="backend.Lineartyping.html#wt_program">wt_program</a> [definition, in <a href="backend.Lineartyping.html">backend.Lineartyping</a>]<br/>
-<a href="backend.RTLtyping.html#wt_program">wt_program</a> [definition, in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.LTLtyping.html#wt_program">wt_program</a> [definition, in <a href="backend.LTLtyping.html">backend.LTLtyping</a>]<br/>
-<a href="backend.Machtyping.html#wt_program">wt_program</a> [definition, in <a href="backend.Machtyping.html">backend.Machtyping</a>]<br/>
-<a href="backend.RTLtyping.html#wt_regset">wt_regset</a> [definition, in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.Machtyping.html#wt_regset">wt_regset</a> [definition, in <a href="backend.Machtyping.html">backend.Machtyping</a>]<br/>
-<a href="backend.RTLtyping.html#wt_regset_assign">wt_regset_assign</a> [lemma, in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.RTLtyping.html#wt_regset_list">wt_regset_list</a> [lemma, in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.Alloctyping.html#wt_regs_for">wt_regs_for</a> [lemma, in <a href="backend.Alloctyping.html">backend.Alloctyping</a>]<br/>
-<a href="backend.Alloctyping.html#wt_regs_for_rec">wt_regs_for_rec</a> [lemma, in <a href="backend.Alloctyping.html">backend.Alloctyping</a>]<br/>
-<a href="backend.Alloctyping.html#wt_reg_for">wt_reg_for</a> [lemma, in <a href="backend.Alloctyping.html">backend.Alloctyping</a>]<br/>
-<a href="backend.Stackingtyping.html#wt_restore_callee_save">wt_restore_callee_save</a> [lemma, in <a href="backend.Stackingtyping.html">backend.Stackingtyping</a>]<br/>
-<a href="backend.Stackingtyping.html#wt_restore_float_callee_save">wt_restore_float_callee_save</a> [lemma, in <a href="backend.Stackingtyping.html">backend.Stackingtyping</a>]<br/>
-<a href="backend.Stackingtyping.html#wt_restore_int_callee_save">wt_restore_int_callee_save</a> [lemma, in <a href="backend.Stackingtyping.html">backend.Stackingtyping</a>]<br/>
-<a href="backend.Alloctyping.html#wt_rtl_function">wt_rtl_function</a> [lemma, in <a href="backend.Alloctyping.html">backend.Alloctyping</a>]<br/>
-<a href="backend.Stackingtyping.html#wt_save_callee_save">wt_save_callee_save</a> [lemma, in <a href="backend.Stackingtyping.html">backend.Stackingtyping</a>]<br/>
-<a href="backend.Stackingtyping.html#wt_save_float_callee_save">wt_save_float_callee_save</a> [lemma, in <a href="backend.Stackingtyping.html">backend.Stackingtyping</a>]<br/>
-<a href="backend.Stackingtyping.html#wt_save_int_callee_save">wt_save_int_callee_save</a> [lemma, in <a href="backend.Stackingtyping.html">backend.Stackingtyping</a>]<br/>
-<a href="backend.Machtyping.html#wt_setreg">wt_setreg</a> [lemma, in <a href="backend.Machtyping.html">backend.Machtyping</a>]<br/>
-<a href="backend.Machtyping.html#wt_set_slot">wt_set_slot</a> [lemma, in <a href="backend.Machtyping.html">backend.Machtyping</a>]<br/>
-<a href="backend.Alloctyping.html#wt_transf_entrypoint">wt_transf_entrypoint</a> [lemma, in <a href="backend.Alloctyping.html">backend.Alloctyping</a>]<br/>
-<a href="backend.Stackingtyping.html#wt_transf_function">wt_transf_function</a> [lemma, in <a href="backend.Stackingtyping.html">backend.Stackingtyping</a>]<br/>
-<a href="backend.Alloctyping.html#wt_transf_function">wt_transf_function</a> [lemma, in <a href="backend.Alloctyping.html">backend.Alloctyping</a>]<br/>
-<a href="backend.Linearizetyping.html#wt_transf_function">wt_transf_function</a> [lemma, in <a href="backend.Linearizetyping.html">backend.Linearizetyping</a>]<br/>
-<a href="backend.Alloctyping.html#wt_transf_instr">wt_transf_instr</a> [lemma, in <a href="backend.Alloctyping.html">backend.Alloctyping</a>]<br/>
-<a href="backend.Alloctyping.html#wt_transf_instrs">wt_transf_instrs</a> [lemma, in <a href="backend.Alloctyping.html">backend.Alloctyping</a>]<br/>
-<a href="backend.Stackingtyping.html#wt_transl_instr">wt_transl_instr</a> [lemma, in <a href="backend.Stackingtyping.html">backend.Stackingtyping</a>]<br/>
-<a href="backend.Tunnelingtyping.html#wt_tunnel_block">wt_tunnel_block</a> [lemma, in <a href="backend.Tunnelingtyping.html">backend.Tunnelingtyping</a>]<br/>
-<a href="backend.Tunnelingtyping.html#wt_tunnel_function">wt_tunnel_function</a> [lemma, in <a href="backend.Tunnelingtyping.html">backend.Tunnelingtyping</a>]<br/>
-<br/><br/><a name="global_X"></a><h2>X </h2>
-<a href="lib.Maps.html#xcombine_l">xcombine_l</a> [definition, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#xcombine_lr">xcombine_lr</a> [lemma, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#xcombine_r">xcombine_r</a> [definition, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#xelements">xelements</a> [definition, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#xelements_complete">xelements_complete</a> [lemma, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#xelements_correct">xelements_correct</a> [lemma, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#xelements_hi">xelements_hi</a> [lemma, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#xelements_ho">xelements_ho</a> [lemma, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#xelements_ih">xelements_ih</a> [lemma, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#xelements_ii">xelements_ii</a> [lemma, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#xelements_io">xelements_io</a> [lemma, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#xelements_keys_norepet">xelements_keys_norepet</a> [lemma, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#xelements_oh">xelements_oh</a> [lemma, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#xelements_oi">xelements_oi</a> [lemma, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#xelements_oo">xelements_oo</a> [lemma, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#xgcombine">xgcombine</a> [lemma, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#xgcombine_l">xgcombine_l</a> [lemma, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#xgcombine_r">xgcombine_r</a> [lemma, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#xget">xget</a> [definition, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#xget_left">xget_left</a> [lemma, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#xgmap">xgmap</a> [lemma, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#xkeys">xkeys</a> [definition, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#xmap">xmap</a> [definition, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="backend.Cmconstr.html#xor">xor</a> [definition, in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Values.html#xor">xor</a> [definition, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="lib.Integers.html#xor">xor</a> [definition, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.PPCgen.html#xorimm">xorimm</a> [definition, in <a href="backend.PPCgen.html">backend.PPCgen</a>]<br/>
-<a href="backend.PPCgenproof1.html#xorimm_correct">xorimm_correct</a> [lemma, in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="lib.Integers.html#xor_assoc">xor_assoc</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Values.html#xor_assoc">xor_assoc</a> [lemma, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Values.html#xor_commut">xor_commut</a> [lemma, in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="lib.Integers.html#xor_commut">xor_commut</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#xor_one_one">xor_one_one</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#xor_zero">xor_zero</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#xor_zero_one">xor_zero_one</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<br/><br/><a name="global_Z"></a><h2>Z </h2>
-<a href="lib.Integers.html#Zdiv_round">Zdiv_round</a> [definition, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Coqlib.html#Zdiv_small">Zdiv_small</a> [lemma, in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#Zdiv_unique">Zdiv_unique</a> [lemma, in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#zeq">zeq</a> [definition, in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#zeq_false">zeq_false</a> [lemma, in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#zeq_true">zeq_true</a> [lemma, in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Integers.html#zero">zero</a> [definition, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Floats.html#zero">zero</a> [axiom, in <a href="lib.Floats.html">lib.Floats</a>]<br/>
-<a href="lib.Maps.html#ZIndexed">ZIndexed</a> [module, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Coqlib.html#zle">zle</a> [definition, in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#zle_false">zle_false</a> [lemma, in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#zle_true">zle_true</a> [lemma, in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#zlt">zlt</a> [definition, in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#zlt_false">zlt_false</a> [lemma, in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#zlt_true">zlt_true</a> [lemma, in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Maps.html#ZMap">ZMap</a> [module, in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Coqlib.html#Zmax_bound_l">Zmax_bound_l</a> [lemma, in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#Zmax_bound_r">Zmax_bound_r</a> [lemma, in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#Zmax_spec">Zmax_spec</a> [lemma, in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#Zmin_spec">Zmin_spec</a> [lemma, in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Integers.html#Zmod_round">Zmod_round</a> [definition, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Coqlib.html#Zmod_small">Zmod_small</a> [lemma, in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#Zmod_unique">Zmod_unique</a> [lemma, in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="backend.Mem.html#ztonat">ztonat</a> [definition, in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="lib.Integers.html#Z_bin_decomp">Z_bin_decomp</a> [definition, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#Z_bin_decomp_range">Z_bin_decomp_range</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#Z_bin_decomp_shift_add">Z_bin_decomp_shift_add</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#Z_of_bits">Z_of_bits</a> [definition, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#Z_of_bits_excl">Z_of_bits_excl</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#Z_of_bits_exten">Z_of_bits_exten</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#Z_of_bits_of_Z">Z_of_bits_of_Z</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#Z_of_bits_range">Z_of_bits_range</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#Z_of_bits_range_2">Z_of_bits_range_2</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#Z_of_bits_shift">Z_of_bits_shift</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#Z_of_bits_shifts">Z_of_bits_shifts</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#Z_of_bits_shifts_rev">Z_of_bits_shifts_rev</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#Z_of_bits_shift_rev">Z_of_bits_shift_rev</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#Z_one_bits">Z_one_bits</a> [definition, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#Z_one_bits_powerserie">Z_one_bits_powerserie</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#Z_one_bits_range">Z_one_bits_range</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#Z_shift_add">Z_shift_add</a> [definition, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#Z_shift_add_bin_decomp">Z_shift_add_bin_decomp</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#Z_shift_add_inj">Z_shift_add_inj</a> [lemma, in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<br/><br/><a name="global__"></a><h2>_ </h2>
-<a href="backend.Lineartyping.html#_">_</a> [constructor, in <a href="backend.Lineartyping.html">backend.Lineartyping</a>]<br/>
-<a href="backend.LTLtyping.html#_">_</a> [constructor, in <a href="backend.LTLtyping.html">backend.LTLtyping</a>]<br/>
-<br/><br/><hr/>
-<h1>Axiom Index</h1>
-<a name="axiom_A"></a><h2>A </h2>
-<a href="lib.Floats.html#abs">abs</a> [in <a href="lib.Floats.html">lib.Floats</a>]<br/>
-<a href="lib.Floats.html#add">add</a> [in <a href="lib.Floats.html">lib.Floats</a>]<br/>
-<a href="lib.Floats.html#addf_commut">addf_commut</a> [in <a href="lib.Floats.html">lib.Floats</a>]<br/>
-<br/><br/><a name="axiom_C"></a><h2>C </h2>
-<a href="lib.Floats.html#cmp">cmp</a> [in <a href="lib.Floats.html">lib.Floats</a>]<br/>
-<a href="lib.Floats.html#cmp_ge_gt_eq">cmp_ge_gt_eq</a> [in <a href="lib.Floats.html">lib.Floats</a>]<br/>
-<a href="lib.Floats.html#cmp_le_lt_eq">cmp_le_lt_eq</a> [in <a href="lib.Floats.html">lib.Floats</a>]<br/>
-<a href="lib.Floats.html#cmp_ne_eq">cmp_ne_eq</a> [in <a href="lib.Floats.html">lib.Floats</a>]<br/>
-<br/><br/><a name="axiom_D"></a><h2>D </h2>
-<a href="lib.Floats.html#div">div</a> [in <a href="lib.Floats.html">lib.Floats</a>]<br/>
-<br/><br/><a name="axiom_E"></a><h2>E </h2>
-<a href="lib.Floats.html#eq_dec">eq_dec</a> [in <a href="lib.Floats.html">lib.Floats</a>]<br/>
-<a href="lib.Floats.html#eq_zero_false">eq_zero_false</a> [in <a href="lib.Floats.html">lib.Floats</a>]<br/>
-<a href="lib.Floats.html#eq_zero_true">eq_zero_true</a> [in <a href="lib.Floats.html">lib.Floats</a>]<br/>
-<a href="lib.Coqlib.html#extensionality">extensionality</a> [in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<br/><br/><a name="axiom_F"></a><h2>F </h2>
-<a href="lib.Floats.html#float">float</a> [in <a href="lib.Floats.html">lib.Floats</a>]<br/>
-<a href="lib.Floats.html#floatofint">floatofint</a> [in <a href="lib.Floats.html">lib.Floats</a>]<br/>
-<a href="lib.Floats.html#floatofintu">floatofintu</a> [in <a href="lib.Floats.html">lib.Floats</a>]<br/>
-<br/><br/><a name="axiom_G"></a><h2>G </h2>
-<a href="backend.Coloring.html#graph_coloring">graph_coloring</a> [in <a href="backend.Coloring.html">backend.Coloring</a>]<br/>
-<br/><br/><a name="axiom_H"></a><h2>H </h2>
-<a href="backend.PPC.html#high_half_signed">high_half_signed</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#high_half_signed_type">high_half_signed_type</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#high_half_unsigned">high_half_unsigned</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#high_half_unsigned_type">high_half_unsigned_type</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<br/><br/><a name="axiom_I"></a><h2>I </h2>
-<a href="lib.Floats.html#intoffloat">intoffloat</a> [in <a href="lib.Floats.html">lib.Floats</a>]<br/>
-<br/><br/><a name="axiom_L"></a><h2>L </h2>
-<a href="backend.PPC.html#low_half_signed">low_half_signed</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#low_half_signed_type">low_half_signed_type</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#low_half_unsigned">low_half_unsigned</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#low_half_unsigned_type">low_half_unsigned_type</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#low_high_half_signed">low_high_half_signed</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#low_high_half_unsigned">low_high_half_unsigned</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<br/><br/><a name="axiom_M"></a><h2>M </h2>
-<a href="backend.RTLgen.html#more_likely">more_likely</a> [in <a href="backend.RTLgen.html">backend.RTLgen</a>]<br/>
-<a href="lib.Floats.html#mul">mul</a> [in <a href="lib.Floats.html">lib.Floats</a>]<br/>
-<br/><br/><a name="axiom_N"></a><h2>N </h2>
-<a href="lib.Floats.html#neg">neg</a> [in <a href="lib.Floats.html">lib.Floats</a>]<br/>
-<a href="lib.Integers.html#neg_mul_distr_l">neg_mul_distr_l</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#neg_mul_distr_r">neg_mul_distr_r</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<br/><br/><a name="axiom_O"></a><h2>O </h2>
-<a href="lib.Floats.html#one">one</a> [in <a href="lib.Floats.html">lib.Floats</a>]<br/>
-<br/><br/><a name="axiom_P"></a><h2>P </h2>
-<a href="lib.Coqlib.html#proof_irrelevance">proof_irrelevance</a> [in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<br/><br/><a name="axiom_S"></a><h2>S </h2>
-<a href="lib.Floats.html#singleoffloat">singleoffloat</a> [in <a href="lib.Floats.html">lib.Floats</a>]<br/>
-<a href="lib.Floats.html#singleoffloat_idem">singleoffloat_idem</a> [in <a href="lib.Floats.html">lib.Floats</a>]<br/>
-<a href="lib.Floats.html#sub">sub</a> [in <a href="lib.Floats.html">lib.Floats</a>]<br/>
-<a href="lib.Floats.html#subf_addf_opp">subf_addf_opp</a> [in <a href="lib.Floats.html">lib.Floats</a>]<br/>
-<br/><br/><a name="axiom_Z"></a><h2>Z </h2>
-<a href="lib.Floats.html#zero">zero</a> [in <a href="lib.Floats.html">lib.Floats</a>]<br/>
-<br/><br/><hr/>
-<h1>Lemma Index</h1>
-<a name="lemma_A"></a><h2>A </h2>
-<a href="backend.Values.html#addf_commut">addf_commut</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.PPCgenproof1.html#addimm_correct">addimm_correct</a> [in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.PPCgenproof1.html#addimm_1_correct">addimm_1_correct</a> [in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.PPCgenproof1.html#addimm_2_correct">addimm_2_correct</a> [in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.Mem.html#address_inject">address_inject</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Constpropproof.html#addr_strength_reduction_correct">addr_strength_reduction_correct</a> [in <a href="backend.Constpropproof.html">backend.Constpropproof</a>]<br/>
-<a href="lib.Integers.html#add_and">add_and</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#add_assoc">add_assoc</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Values.html#add_assoc">add_assoc</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Allocproof.html#add_call_correct">add_call_correct</a> [in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="lib.Integers.html#add_commut">add_commut</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Values.html#add_commut">add_commut</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Allocproof.html#add_cond_correct">add_cond_correct</a> [in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.Coloringproof.html#add_edges_instrs_correct">add_edges_instrs_correct</a> [in <a href="backend.Coloringproof.html">backend.Coloringproof</a>]<br/>
-<a href="backend.Coloringproof.html#add_edges_instrs_correct_aux">add_edges_instrs_correct_aux</a> [in <a href="backend.Coloringproof.html">backend.Coloringproof</a>]<br/>
-<a href="backend.Coloringproof.html#add_edges_instrs_incl_aux">add_edges_instrs_incl_aux</a> [in <a href="backend.Coloringproof.html">backend.Coloringproof</a>]<br/>
-<a href="backend.Coloringproof.html#add_edges_instr_correct">add_edges_instr_correct</a> [in <a href="backend.Coloringproof.html">backend.Coloringproof</a>]<br/>
-<a href="backend.Coloringproof.html#add_edges_instr_incl">add_edges_instr_incl</a> [in <a href="backend.Coloringproof.html">backend.Coloringproof</a>]<br/>
-<a href="backend.Allocproof.html#add_entry_correct">add_entry_correct</a> [in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.Globalenvs.html#add_functs_transf">add_functs_transf</a> [in <a href="backend.Globalenvs.html">backend.Globalenvs</a>]<br/>
-<a href="backend.RTLgenproof1.html#add_instr_at">add_instr_at</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#add_instr_incr">add_instr_incr</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgen.html#add_instr_wf">add_instr_wf</a> [in <a href="backend.RTLgen.html">backend.RTLgen</a>]<br/>
-<a href="backend.Coloringproof.html#add_interf_call_correct">add_interf_call_correct</a> [in <a href="backend.Coloringproof.html">backend.Coloringproof</a>]<br/>
-<a href="backend.Coloringproof.html#add_interf_call_correct_aux_1">add_interf_call_correct_aux_1</a> [in <a href="backend.Coloringproof.html">backend.Coloringproof</a>]<br/>
-<a href="backend.Coloringproof.html#add_interf_call_correct_aux_2">add_interf_call_correct_aux_2</a> [in <a href="backend.Coloringproof.html">backend.Coloringproof</a>]<br/>
-<a href="backend.Coloringproof.html#add_interf_call_incl">add_interf_call_incl</a> [in <a href="backend.Coloringproof.html">backend.Coloringproof</a>]<br/>
-<a href="backend.Coloringproof.html#add_interf_call_incl_aux_1">add_interf_call_incl_aux_1</a> [in <a href="backend.Coloringproof.html">backend.Coloringproof</a>]<br/>
-<a href="backend.Coloringproof.html#add_interf_call_incl_aux_2">add_interf_call_incl_aux_2</a> [in <a href="backend.Coloringproof.html">backend.Coloringproof</a>]<br/>
-<a href="backend.InterfGraph.html#add_interf_correct">add_interf_correct</a> [in <a href="backend.InterfGraph.html">backend.InterfGraph</a>]<br/>
-<a href="backend.Coloringproof.html#add_interf_entry_correct">add_interf_entry_correct</a> [in <a href="backend.Coloringproof.html">backend.Coloringproof</a>]<br/>
-<a href="backend.Coloringproof.html#add_interf_entry_incl">add_interf_entry_incl</a> [in <a href="backend.Coloringproof.html">backend.Coloringproof</a>]<br/>
-<a href="backend.InterfGraph.html#add_interf_incl">add_interf_incl</a> [in <a href="backend.InterfGraph.html">backend.InterfGraph</a>]<br/>
-<a href="backend.Coloringproof.html#add_interf_live_correct">add_interf_live_correct</a> [in <a href="backend.Coloringproof.html">backend.Coloringproof</a>]<br/>
-<a href="backend.Coloringproof.html#add_interf_live_correct_aux">add_interf_live_correct_aux</a> [in <a href="backend.Coloringproof.html">backend.Coloringproof</a>]<br/>
-<a href="backend.Coloringproof.html#add_interf_live_incl">add_interf_live_incl</a> [in <a href="backend.Coloringproof.html">backend.Coloringproof</a>]<br/>
-<a href="backend.Coloringproof.html#add_interf_live_incl_aux">add_interf_live_incl_aux</a> [in <a href="backend.Coloringproof.html">backend.Coloringproof</a>]<br/>
-<a href="backend.Coloringproof.html#add_interf_move_correct">add_interf_move_correct</a> [in <a href="backend.Coloringproof.html">backend.Coloringproof</a>]<br/>
-<a href="backend.Coloringproof.html#add_interf_move_incl">add_interf_move_incl</a> [in <a href="backend.Coloringproof.html">backend.Coloringproof</a>]<br/>
-<a href="backend.InterfGraph.html#add_interf_mreg_correct">add_interf_mreg_correct</a> [in <a href="backend.InterfGraph.html">backend.InterfGraph</a>]<br/>
-<a href="backend.InterfGraph.html#add_interf_mreg_incl">add_interf_mreg_incl</a> [in <a href="backend.InterfGraph.html">backend.InterfGraph</a>]<br/>
-<a href="backend.Coloringproof.html#add_interf_op_correct">add_interf_op_correct</a> [in <a href="backend.Coloringproof.html">backend.Coloringproof</a>]<br/>
-<a href="backend.Coloringproof.html#add_interf_op_incl">add_interf_op_incl</a> [in <a href="backend.Coloringproof.html">backend.Coloringproof</a>]<br/>
-<a href="backend.Coloringproof.html#add_interf_params_correct">add_interf_params_correct</a> [in <a href="backend.Coloringproof.html">backend.Coloringproof</a>]<br/>
-<a href="backend.Coloringproof.html#add_interf_params_correct_aux">add_interf_params_correct_aux</a> [in <a href="backend.Coloringproof.html">backend.Coloringproof</a>]<br/>
-<a href="backend.Coloringproof.html#add_interf_params_incl">add_interf_params_incl</a> [in <a href="backend.Coloringproof.html">backend.Coloringproof</a>]<br/>
-<a href="backend.Coloringproof.html#add_interf_params_incl_aux">add_interf_params_incl_aux</a> [in <a href="backend.Coloringproof.html">backend.Coloringproof</a>]<br/>
-<a href="backend.RTLgenproof1.html#add_letvar_wf">add_letvar_wf</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.Allocproof.html#add_load_correct">add_load_correct</a> [in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.CSEproof.html#add_load_satisfiable">add_load_satisfiable</a> [in <a href="backend.CSEproof.html">backend.CSEproof</a>]<br/>
-<a href="backend.RTLgenproof.html#add_move_correct">add_move_correct</a> [in <a href="backend.RTLgenproof.html">backend.RTLgenproof</a>]<br/>
-<a href="backend.Allocproof.html#add_move_correct">add_move_correct</a> [in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.RTLgenproof1.html#add_move_incr">add_move_incr</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="lib.Integers.html#add_neg_zero">add_neg_zero</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Allocproof.html#add_op_correct">add_op_correct</a> [in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.CSEproof.html#add_op_satisfiable">add_op_satisfiable</a> [in <a href="backend.CSEproof.html">backend.CSEproof</a>]<br/>
-<a href="backend.Values.html#add_permut">add_permut</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="lib.Integers.html#add_permut">add_permut</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Values.html#add_permut_4">add_permut_4</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Coloringproof.html#add_prefs_call_incl">add_prefs_call_incl</a> [in <a href="backend.Coloringproof.html">backend.Coloringproof</a>]<br/>
-<a href="backend.InterfGraph.html#add_pref_incl">add_pref_incl</a> [in <a href="backend.InterfGraph.html">backend.InterfGraph</a>]<br/>
-<a href="backend.InterfGraph.html#add_pref_mreg_incl">add_pref_mreg_incl</a> [in <a href="backend.InterfGraph.html">backend.InterfGraph</a>]<br/>
-<a href="backend.Allocproof.html#add_reloads_correct">add_reloads_correct</a> [in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.Allocproof.html#add_reloads_correct_rec">add_reloads_correct_rec</a> [in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.Allocproof.html#add_reload_correct">add_reload_correct</a> [in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.Allocproof.html#add_return_correct">add_return_correct</a> [in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.CSEproof.html#add_rhs_satisfiable">add_rhs_satisfiable</a> [in <a href="backend.CSEproof.html">backend.CSEproof</a>]<br/>
-<a href="lib.Integers.html#add_signed">add_signed</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Allocproof.html#add_spill_correct">add_spill_correct</a> [in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.Allocproof.html#add_store_correct">add_store_correct</a> [in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.Kildall.html#add_successors_correct">add_successors_correct</a> [in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Kildall.html#add_to_worklist_1">add_to_worklist_1</a> [in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Kildall.html#add_to_worklist_2">add_to_worklist_2</a> [in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Allocproof.html#add_undefs_correct">add_undefs_correct</a> [in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="lib.Integers.html#add_unsigned">add_unsigned</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.RTLgenproof1.html#add_vars_incr">add_vars_incr</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#add_vars_letenv">add_vars_letenv</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#add_vars_valid">add_vars_valid</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#add_vars_wf">add_vars_wf</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#add_var_find">add_var_find</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#add_var_incr">add_var_incr</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#add_var_letenv">add_var_letenv</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#add_var_valid">add_var_valid</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#add_var_wf">add_var_wf</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="lib.Integers.html#add_zero">add_zero</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Allocproof.html#agree_assign_dead">agree_assign_dead</a> [in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.Allocproof.html#agree_assign_live">agree_assign_live</a> [in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.Allocproof.html#agree_call">agree_call</a> [in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.Stackingproof.html#agree_eval_reg">agree_eval_reg</a> [in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="backend.Allocproof.html#agree_eval_reg">agree_eval_reg</a> [in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.Stackingproof.html#agree_eval_regs">agree_eval_regs</a> [in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="backend.Allocproof.html#agree_eval_regs">agree_eval_regs</a> [in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.Allocproof.html#agree_exten">agree_exten</a> [in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.PPCgenproof1.html#agree_exten_1">agree_exten_1</a> [in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.PPCgenproof1.html#agree_exten_2">agree_exten_2</a> [in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.Allocproof.html#agree_increasing">agree_increasing</a> [in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.Allocproof.html#agree_init_regs">agree_init_regs</a> [in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.Allocproof.html#agree_move_live">agree_move_live</a> [in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.PPCgenproof1.html#agree_nextinstr">agree_nextinstr</a> [in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.PPCgenproof1.html#agree_nextinstr_commut">agree_nextinstr_commut</a> [in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.Allocproof.html#agree_parameters">agree_parameters</a> [in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.Allocproof.html#agree_reg_list_live">agree_reg_list_live</a> [in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.Allocproof.html#agree_reg_live">agree_reg_live</a> [in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.Allocproof.html#agree_reg_sum_live">agree_reg_sum_live</a> [in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.Stackingproof.html#agree_return_regs">agree_return_regs</a> [in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="backend.PPCgenproof1.html#agree_set_commut">agree_set_commut</a> [in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.Stackingproof.html#agree_set_local">agree_set_local</a> [in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="backend.PPCgenproof1.html#agree_set_mfreg">agree_set_mfreg</a> [in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.PPCgenproof1.html#agree_set_mireg">agree_set_mireg</a> [in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.PPCgenproof1.html#agree_set_mireg_exten">agree_set_mireg_exten</a> [in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.PPCgenproof1.html#agree_set_mireg_twice">agree_set_mireg_twice</a> [in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.PPCgenproof1.html#agree_set_mreg">agree_set_mreg</a> [in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.PPCgenproof1.html#agree_set_other">agree_set_other</a> [in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.Stackingproof.html#agree_set_outgoing">agree_set_outgoing</a> [in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="backend.Stackingproof.html#agree_set_reg">agree_set_reg</a> [in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="backend.PPCgenproof1.html#agree_set_twice_mireg">agree_set_twice_mireg</a> [in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="lib.Coqlib.html#align_le">align_le</a> [in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="backend.Alloctyping.html#allocs_write_ok">allocs_write_ok</a> [in <a href="backend.Alloctyping.html">backend.Alloctyping</a>]<br/>
-<a href="backend.Mem.html#alloc_extends">alloc_extends</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#alloc_mapped_inject">alloc_mapped_inject</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Coloringproof.html#alloc_of_coloring_correct_1">alloc_of_coloring_correct_1</a> [in <a href="backend.Coloringproof.html">backend.Coloringproof</a>]<br/>
-<a href="backend.Coloringproof.html#alloc_of_coloring_correct_2">alloc_of_coloring_correct_2</a> [in <a href="backend.Coloringproof.html">backend.Coloringproof</a>]<br/>
-<a href="backend.Coloringproof.html#alloc_of_coloring_correct_3">alloc_of_coloring_correct_3</a> [in <a href="backend.Coloringproof.html">backend.Coloringproof</a>]<br/>
-<a href="backend.Coloringproof.html#alloc_of_coloring_correct_4">alloc_of_coloring_correct_4</a> [in <a href="backend.Coloringproof.html">backend.Coloringproof</a>]<br/>
-<a href="backend.RTLgenproof1.html#alloc_regs_fresh_or_in_map">alloc_regs_fresh_or_in_map</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#alloc_regs_incr">alloc_regs_incr</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#alloc_regs_target_ok">alloc_regs_target_ok</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#alloc_regs_valid">alloc_regs_valid</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#alloc_reg_fresh_or_in_map">alloc_reg_fresh_or_in_map</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#alloc_reg_incr">alloc_reg_incr</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#alloc_reg_target_ok">alloc_reg_target_ok</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#alloc_reg_valid">alloc_reg_valid</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.Mem.html#alloc_right_inject">alloc_right_inject</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Alloctyping.html#alloc_type">alloc_type</a> [in <a href="backend.Alloctyping.html">backend.Alloctyping</a>]<br/>
-<a href="backend.Alloctyping.html#alloc_types">alloc_types</a> [in <a href="backend.Alloctyping.html">backend.Alloctyping</a>]<br/>
-<a href="backend.Mem.html#alloc_unmapped_inject">alloc_unmapped_inject</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Cminorgenproof.html#alloc_variables_list_block">alloc_variables_list_block</a> [in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#alloc_variables_nextblock_incr">alloc_variables_nextblock_incr</a> [in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Alloctyping.html#alloc_write_ok">alloc_write_ok</a> [in <a href="backend.Alloctyping.html">backend.Alloctyping</a>]<br/>
-<a href="backend.InterfGraph.html#all_interf_regs_correct_aux_1">all_interf_regs_correct_aux_1</a> [in <a href="backend.InterfGraph.html">backend.InterfGraph</a>]<br/>
-<a href="backend.InterfGraph.html#all_interf_regs_correct_aux_2">all_interf_regs_correct_aux_2</a> [in <a href="backend.InterfGraph.html">backend.InterfGraph</a>]<br/>
-<a href="backend.InterfGraph.html#all_interf_regs_correct_aux_3">all_interf_regs_correct_aux_3</a> [in <a href="backend.InterfGraph.html">backend.InterfGraph</a>]<br/>
-<a href="backend.InterfGraph.html#all_interf_regs_correct_1">all_interf_regs_correct_1</a> [in <a href="backend.InterfGraph.html">backend.InterfGraph</a>]<br/>
-<a href="backend.InterfGraph.html#all_interf_regs_correct_2">all_interf_regs_correct_2</a> [in <a href="backend.InterfGraph.html">backend.InterfGraph</a>]<br/>
-<a href="backend.CSEproof.html#analysis_correct_entry">analysis_correct_entry</a> [in <a href="backend.CSEproof.html">backend.CSEproof</a>]<br/>
-<a href="backend.CSEproof.html#analysis_correct_N">analysis_correct_N</a> [in <a href="backend.CSEproof.html">backend.CSEproof</a>]<br/>
-<a href="backend.CSEproof.html#analysis_correct_1">analysis_correct_1</a> [in <a href="backend.CSEproof.html">backend.CSEproof</a>]<br/>
-<a href="backend.Allocproof.html#analyze_correct">analyze_correct</a> [in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.Constpropproof.html#analyze_correct_1">analyze_correct_1</a> [in <a href="backend.Constpropproof.html">backend.Constpropproof</a>]<br/>
-<a href="backend.Constpropproof.html#analyze_correct_2">analyze_correct_2</a> [in <a href="backend.Constpropproof.html">backend.Constpropproof</a>]<br/>
-<a href="backend.Constpropproof.html#analyze_correct_3">analyze_correct_3</a> [in <a href="backend.Constpropproof.html">backend.Constpropproof</a>]<br/>
-<a href="backend.Kildall.html#analyze_invariant">analyze_invariant</a> [in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Kildall.html#analyze_P">analyze_P</a> [in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.PPCgenproof1.html#andimm_correct">andimm_correct</a> [in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.Values.html#and_assoc">and_assoc</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="lib.Integers.html#and_assoc">and_assoc</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#and_commut">and_commut</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Values.html#and_commut">and_commut</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="lib.Integers.html#and_idem">and_idem</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#and_mone">and_mone</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#and_or_distrib">and_or_distrib</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#and_shl">and_shl</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#and_shru">and_shru</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#and_xor_distrib">and_xor_distrib</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#and_zero">and_zero</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Parallelmove.html#appcons_length">appcons_length</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="lib.Maps.html#append_assoc_0">append_assoc_0</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#append_assoc_1">append_assoc_1</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#append_injective">append_injective</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#append_neutral_l">append_neutral_l</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#append_neutral_r">append_neutral_r</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="backend.Main.html#apply_total_transf_program">apply_total_transf_program</a> [in <a href="backend.Main.html">backend.Main</a>]<br/>
-<a href="backend.Constpropproof.html#approx_regs_val_list">approx_regs_val_list</a> [in <a href="backend.Constpropproof.html">backend.Constpropproof</a>]<br/>
-<a href="backend.Parallelmove.html#app_app">app_app</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#app_cons">app_cons</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#app_nil">app_nil</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#app_rewrite">app_rewrite</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#app_rewriter">app_rewriter</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#app_rewrite2">app_rewrite2</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Conventions.html#arguments_not_preserved">arguments_not_preserved</a> [in <a href="backend.Conventions.html">backend.Conventions</a>]<br/>
-<br/><br/><a name="lemma_B"></a><h2>B </h2>
-<a href="backend.Cminorgenproof.html#bind_parameters_length">bind_parameters_length</a> [in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="lib.Integers.html#bits_of_Z_above">bits_of_Z_above</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#bits_of_Z_below">bits_of_Z_below</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#bits_of_Z_mone">bits_of_Z_mone</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#bits_of_Z_of_bits">bits_of_Z_of_bits</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#bits_of_Z_zero">bits_of_Z_zero</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#bitwise_binop_assoc">bitwise_binop_assoc</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#bitwise_binop_commut">bitwise_binop_commut</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#bitwise_binop_idem">bitwise_binop_idem</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#bitwise_binop_rol">bitwise_binop_rol</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#bitwise_binop_shl">bitwise_binop_shl</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#bitwise_binop_shru">bitwise_binop_shru</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Mem.html#block_agree_refl">block_agree_refl</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#block_agree_sym">block_agree_sym</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#block_agree_trans">block_agree_trans</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#block_contents_exten">block_contents_exten</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#block_contents_inject_incr">block_contents_inject_incr</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#block_cont_val">block_cont_val</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Values.html#bool_of_false_val">bool_of_false_val</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Values.html#bool_of_false_val2">bool_of_false_val2</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Values.html#bool_of_false_val_inv">bool_of_false_val_inv</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Values.html#bool_of_true_val">bool_of_true_val</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Values.html#bool_of_true_val2">bool_of_true_val2</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Values.html#bool_of_true_val_inv">bool_of_true_val_inv</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Mem.html#bounds_free_block">bounds_free_block</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Lineartyping.html#bound_float_callee_save_pos">bound_float_callee_save_pos</a> [in <a href="backend.Lineartyping.html">backend.Lineartyping</a>]<br/>
-<a href="backend.Lineartyping.html#bound_float_local_pos">bound_float_local_pos</a> [in <a href="backend.Lineartyping.html">backend.Lineartyping</a>]<br/>
-<a href="backend.Lineartyping.html#bound_int_callee_save_pos">bound_int_callee_save_pos</a> [in <a href="backend.Lineartyping.html">backend.Lineartyping</a>]<br/>
-<a href="backend.Lineartyping.html#bound_int_local_pos">bound_int_local_pos</a> [in <a href="backend.Lineartyping.html">backend.Lineartyping</a>]<br/>
-<a href="backend.Lineartyping.html#bound_outgoing_pos">bound_outgoing_pos</a> [in <a href="backend.Lineartyping.html">backend.Lineartyping</a>]<br/>
-<a href="backend.Tunnelingproof.html#branch_target_characterization">branch_target_characterization</a> [in <a href="backend.Tunnelingproof.html">backend.Tunnelingproof</a>]<br/>
-<a href="backend.Tunnelingproof.html#branch_target_rec_1">branch_target_rec_1</a> [in <a href="backend.Tunnelingproof.html">backend.Tunnelingproof</a>]<br/>
-<a href="backend.Tunnelingproof.html#branch_target_rec_2">branch_target_rec_2</a> [in <a href="backend.Tunnelingproof.html">backend.Tunnelingproof</a>]<br/>
-<br/><br/><a name="lemma_C"></a><h2>C </h2>
-<a href="backend.Machabstr2mach.html#callstack_dom_diff">callstack_dom_diff</a> [in <a href="backend.Machabstr2mach.html">backend.Machabstr2mach</a>]<br/>
-<a href="backend.Machabstr2mach.html#callstack_dom_incr">callstack_dom_incr</a> [in <a href="backend.Machabstr2mach.html">backend.Machabstr2mach</a>]<br/>
-<a href="backend.Machabstr2mach.html#callstack_dom_less">callstack_dom_less</a> [in <a href="backend.Machabstr2mach.html">backend.Machabstr2mach</a>]<br/>
-<a href="backend.Machabstr2mach.html#callstack_exten">callstack_exten</a> [in <a href="backend.Machabstr2mach.html">backend.Machabstr2mach</a>]<br/>
-<a href="backend.Machabstr2mach.html#callstack_function_entry">callstack_function_entry</a> [in <a href="backend.Machabstr2mach.html">backend.Machabstr2mach</a>]<br/>
-<a href="backend.Machabstr2mach.html#callstack_function_return">callstack_function_return</a> [in <a href="backend.Machabstr2mach.html">backend.Machabstr2mach</a>]<br/>
-<a href="backend.Machabstr2mach.html#callstack_get_parent">callstack_get_parent</a> [in <a href="backend.Machabstr2mach.html">backend.Machabstr2mach</a>]<br/>
-<a href="backend.Machabstr2mach.html#callstack_get_slot">callstack_get_slot</a> [in <a href="backend.Machabstr2mach.html">backend.Machabstr2mach</a>]<br/>
-<a href="backend.Machabstr2mach.html#callstack_init">callstack_init</a> [in <a href="backend.Machabstr2mach.html">backend.Machabstr2mach</a>]<br/>
-<a href="backend.Machabstr2mach.html#callstack_load">callstack_load</a> [in <a href="backend.Machabstr2mach.html">backend.Machabstr2mach</a>]<br/>
-<a href="backend.Machabstr2mach.html#callstack_set_slot">callstack_set_slot</a> [in <a href="backend.Machabstr2mach.html">backend.Machabstr2mach</a>]<br/>
-<a href="backend.Machabstr2mach.html#callstack_store">callstack_store</a> [in <a href="backend.Machabstr2mach.html">backend.Machabstr2mach</a>]<br/>
-<a href="backend.Machabstr2mach.html#callstack_store_aux">callstack_store_aux</a> [in <a href="backend.Machabstr2mach.html">backend.Machabstr2mach</a>]<br/>
-<a href="backend.Machabstr2mach.html#callstack_store_ok">callstack_store_ok</a> [in <a href="backend.Machabstr2mach.html">backend.Machabstr2mach</a>]<br/>
-<a href="backend.Allocproof.html#call_regs_param_of_arg">call_regs_param_of_arg</a> [in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="lib.Integers.html#cast16unsigned_and">cast16unsigned_and</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Values.html#cast16unsigned_and">cast16unsigned_and</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="lib.Integers.html#cast16_signed_equal_if_unsigned_equal">cast16_signed_equal_if_unsigned_equal</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#cast16_signed_idem">cast16_signed_idem</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#cast16_unsigned_idem">cast16_unsigned_idem</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#cast16_unsigned_signed">cast16_unsigned_signed</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#cast8unsigned_and">cast8unsigned_and</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Values.html#cast8unsigned_and">cast8unsigned_and</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="lib.Integers.html#cast8_signed_equal_if_unsigned_equal">cast8_signed_equal_if_unsigned_equal</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#cast8_signed_idem">cast8_signed_idem</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#cast8_signed_unsigned">cast8_signed_unsigned</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#cast8_unsigned_idem">cast8_unsigned_idem</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#cast8_unsigned_signed">cast8_unsigned_signed</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Inclusion.html#check_all_leaves_sound">check_all_leaves_sound</a> [in <a href="lib.Inclusion.html">lib.Inclusion</a>]<br/>
-<a href="backend.Coloringproof.html#check_coloring_1_correct">check_coloring_1_correct</a> [in <a href="backend.Coloringproof.html">backend.Coloringproof</a>]<br/>
-<a href="backend.Coloringproof.html#check_coloring_2_correct">check_coloring_2_correct</a> [in <a href="backend.Coloringproof.html">backend.Coloringproof</a>]<br/>
-<a href="backend.Coloringproof.html#check_coloring_3_correct">check_coloring_3_correct</a> [in <a href="backend.Coloringproof.html">backend.Coloringproof</a>]<br/>
-<a href="backend.Mem.html#check_cont_agree">check_cont_agree</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#check_cont_false">check_cont_false</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#check_cont_inject">check_cont_inject</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#check_cont_inv">check_cont_inv</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#check_cont_true">check_cont_true</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="lib.Integers.html#check_equal_on_range_correct">check_equal_on_range_correct</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Linearizetyping.html#cleanup_code_conservation">cleanup_code_conservation</a> [in <a href="backend.Linearizetyping.html">backend.Linearizetyping</a>]<br/>
-<a href="backend.Linearizetyping.html#cleanup_code_conservation_2">cleanup_code_conservation_2</a> [in <a href="backend.Linearizetyping.html">backend.Linearizetyping</a>]<br/>
-<a href="backend.Linearizeproof.html#cleanup_code_correct_1">cleanup_code_correct_1</a> [in <a href="backend.Linearizeproof.html">backend.Linearizeproof</a>]<br/>
-<a href="backend.Linearizeproof.html#cleanup_code_correct_2">cleanup_code_correct_2</a> [in <a href="backend.Linearizeproof.html">backend.Linearizeproof</a>]<br/>
-<a href="backend.Linearizetyping.html#cleanup_function_conservation">cleanup_function_conservation</a> [in <a href="backend.Linearizetyping.html">backend.Linearizetyping</a>]<br/>
-<a href="backend.Linearizetyping.html#cleanup_function_conservation_2">cleanup_function_conservation_2</a> [in <a href="backend.Linearizetyping.html">backend.Linearizetyping</a>]<br/>
-<a href="backend.Linearizeproof.html#cleanup_function_correct">cleanup_function_correct</a> [in <a href="backend.Linearizeproof.html">backend.Linearizeproof</a>]<br/>
-<a href="backend.Values.html#cmpf_ge">cmpf_ge</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Values.html#cmpf_is_bool">cmpf_is_bool</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Values.html#cmpf_le">cmpf_le</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Values.html#cmpu_is_bool">cmpu_is_bool</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Values.html#cmp_is_bool">cmp_is_bool</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Values.html#cmp_mismatch_is_bool">cmp_mismatch_is_bool</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.PPCgenproof.html#code_tail_next">code_tail_next</a> [in <a href="backend.PPCgenproof.html">backend.PPCgenproof</a>]<br/>
-<a href="backend.PPCgenproof.html#code_tail_next_int">code_tail_next_int</a> [in <a href="backend.PPCgenproof.html">backend.PPCgenproof</a>]<br/>
-<a href="lib.Maps.html#combine_commut">combine_commut</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Ordered.html#compare">compare</a> [in <a href="lib.Ordered.html">lib.Ordered</a>]<br/>
-<a href="lib.Ordered.html#compare">compare</a> [in <a href="lib.Ordered.html">lib.Ordered</a>]<br/>
-<a href="lib.Ordered.html#compare">compare</a> [in <a href="lib.Ordered.html">lib.Ordered</a>]<br/>
-<a href="backend.PPCgenproof1.html#compare_float_spec">compare_float_spec</a> [in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.PPCgenproof1.html#compare_sint_spec">compare_sint_spec</a> [in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.PPCgenproof1.html#compare_uint_spec">compare_uint_spec</a> [in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.Constpropproof.html#cond_strength_reduction_correct">cond_strength_reduction_correct</a> [in <a href="backend.Constpropproof.html">backend.Constpropproof</a>]<br/>
-<a href="backend.RTLtyping.html#consistent_not_eq">consistent_not_eq</a> [in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.Parallelmove.html#cons_replace">cons_replace</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Mem.html#contentmap_inject_incr">contentmap_inject_incr</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#content_inject_incr">content_inject_incr</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Coloringproof.html#correct_interf_alloc_instr">correct_interf_alloc_instr</a> [in <a href="backend.Coloringproof.html">backend.Coloringproof</a>]<br/>
-<a href="backend.Coloringproof.html#correct_interf_instr_incl">correct_interf_instr_incl</a> [in <a href="backend.Coloringproof.html">backend.Coloringproof</a>]<br/>
-<br/><br/><a name="lemma_D"></a><h2>D </h2>
-<a href="backend.RTLtyping.html#definite_included">definite_included</a> [in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.Locations.html#diff_not_eq">diff_not_eq</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#diff_sym">diff_sym</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Kildall.html#discard_top_worklist_invariant">discard_top_worklist_invariant</a> [in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Parallelmove.html#disc1">disc1</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#disc2">disc2</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Locations.html#disjoint_cons_left">disjoint_cons_left</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#disjoint_cons_right">disjoint_cons_right</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#disjoint_notin">disjoint_notin</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#disjoint_sym">disjoint_sym</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Parallelmove.html#disjoint_tmp__noTmp">disjoint_tmp__noTmp</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Allocproof_aux.html#dis_dsttmp1_pnilnil">dis_dsttmp1_pnilnil</a> [in <a href="backend.Allocproof_aux.html">backend.Allocproof_aux</a>]<br/>
-<a href="backend.Allocproof_aux.html#dis_srctmp1_pnilnil">dis_srctmp1_pnilnil</a> [in <a href="backend.Allocproof_aux.html">backend.Allocproof_aux</a>]<br/>
-<a href="lib.Integers.html#divs_pow2">divs_pow2</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Values.html#divs_pow2">divs_pow2</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Values.html#divu_pow2">divu_pow2</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="lib.Integers.html#divu_pow2">divu_pow2</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Allocproof_aux.html#Done_notmp1src_inv">Done_notmp1src_inv</a> [in <a href="backend.Allocproof_aux.html">backend.Allocproof_aux</a>]<br/>
-<a href="backend.Allocproof_aux.html#Done_notmp1src_invf">Done_notmp1src_invf</a> [in <a href="backend.Allocproof_aux.html">backend.Allocproof_aux</a>]<br/>
-<a href="backend.Allocproof_aux.html#Done_notmp1src_invpp">Done_notmp1src_invpp</a> [in <a href="backend.Allocproof_aux.html">backend.Allocproof_aux</a>]<br/>
-<a href="backend.Allocproof_aux.html#Done_notmp1src_res">Done_notmp1src_res</a> [in <a href="backend.Allocproof_aux.html">backend.Allocproof_aux</a>]<br/>
-<a href="backend.Allocproof_aux.html#Done_notmp1_inv">Done_notmp1_inv</a> [in <a href="backend.Allocproof_aux.html">backend.Allocproof_aux</a>]<br/>
-<a href="backend.Allocproof_aux.html#Done_notmp1_invf">Done_notmp1_invf</a> [in <a href="backend.Allocproof_aux.html">backend.Allocproof_aux</a>]<br/>
-<a href="backend.Allocproof_aux.html#Done_notmp1_invpp">Done_notmp1_invpp</a> [in <a href="backend.Allocproof_aux.html">backend.Allocproof_aux</a>]<br/>
-<a href="backend.Allocproof_aux.html#Done_notmp1_res">Done_notmp1_res</a> [in <a href="backend.Allocproof_aux.html">backend.Allocproof_aux</a>]<br/>
-<a href="backend.Allocproof_aux.html#Done_notmp3_inv">Done_notmp3_inv</a> [in <a href="backend.Allocproof_aux.html">backend.Allocproof_aux</a>]<br/>
-<a href="backend.Allocproof_aux.html#Done_notmp3_invf">Done_notmp3_invf</a> [in <a href="backend.Allocproof_aux.html">backend.Allocproof_aux</a>]<br/>
-<a href="backend.Allocproof_aux.html#Done_notmp3_invpp">Done_notmp3_invpp</a> [in <a href="backend.Allocproof_aux.html">backend.Allocproof_aux</a>]<br/>
-<a href="backend.Allocproof_aux.html#Done_notmp3_res">Done_notmp3_res</a> [in <a href="backend.Allocproof_aux.html">backend.Allocproof_aux</a>]<br/>
-<a href="backend.Parallelmove.html#dstepp_sameExec">dstepp_sameExec</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#dstepp_stepp">dstepp_stepp</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#dstep_inv">dstep_inv</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#dstep_inv_getdst">dstep_inv_getdst</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#dstep_step">dstep_step</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Allocproof_aux.html#dst_tmp2_res">dst_tmp2_res</a> [in <a href="backend.Allocproof_aux.html">backend.Allocproof_aux</a>]<br/>
-<a href="backend.Allocproof_aux.html#dst_tmp2_step">dst_tmp2_step</a> [in <a href="backend.Allocproof_aux.html">backend.Allocproof_aux</a>]<br/>
-<a href="backend.Allocproof_aux.html#dst_tmp2_stepf">dst_tmp2_stepf</a> [in <a href="backend.Allocproof_aux.html">backend.Allocproof_aux</a>]<br/>
-<a href="backend.Allocproof_aux.html#dst_tmp2_stepp">dst_tmp2_stepp</a> [in <a href="backend.Allocproof_aux.html">backend.Allocproof_aux</a>]<br/>
-<br/><br/><a name="lemma_E"></a><h2>E </h2>
-<a href="lib.Maps.html#elements_complete">elements_complete</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Sets.html#elements_complete">elements_complete</a> [in <a href="lib.Sets.html">lib.Sets</a>]<br/>
-<a href="lib.Maps.html#elements_correct">elements_correct</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Sets.html#elements_correct">elements_correct</a> [in <a href="lib.Sets.html">lib.Sets</a>]<br/>
-<a href="lib.Maps.html#elements_keys_norepet">elements_keys_norepet</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="backend.CSE.html#empty_numbering_satisfiable">empty_numbering_satisfiable</a> [in <a href="backend.CSE.html">backend.CSE</a>]<br/>
-<a href="backend.RTLtyping.html#encode_decode">encode_decode</a> [in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.RTLtyping.html#encode_injective">encode_injective</a> [in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.Allocproof.html#entrypoint_function_translated">entrypoint_function_translated</a> [in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.Linearizeproof.html#enumerate_complete">enumerate_complete</a> [in <a href="backend.Linearizeproof.html">backend.Linearizeproof</a>]<br/>
-<a href="backend.Linearizeproof.html#enumerate_head">enumerate_head</a> [in <a href="backend.Linearizeproof.html">backend.Linearizeproof</a>]<br/>
-<a href="backend.Linearizeproof.html#enumerate_norepet">enumerate_norepet</a> [in <a href="backend.Linearizeproof.html">backend.Linearizeproof</a>]<br/>
-<a href="backend.Constprop.html#eq">eq</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="lib.Lattice.html#eq">eq</a> [in <a href="lib.Lattice.html">lib.Lattice</a>]<br/>
-<a href="lib.Sets.html#eq">eq</a> [in <a href="lib.Sets.html">lib.Sets</a>]<br/>
-<a href="lib.Lattice.html#eq">eq</a> [in <a href="lib.Lattice.html">lib.Lattice</a>]<br/>
-<a href="lib.Lattice.html#eq">eq</a> [in <a href="lib.Lattice.html">lib.Lattice</a>]<br/>
-<a href="backend.Locations.html#eq">eq</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="lib.Maps.html#eq">eq</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#eq">eq</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Integers.html#eqmod_add">eqmod_add</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#eqmod_mod">eqmod_mod</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#eqmod_mod_eq">eqmod_mod_eq</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#eqmod_mult">eqmod_mult</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#eqmod_neg">eqmod_neg</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#eqmod_refl">eqmod_refl</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#eqmod_refl2">eqmod_refl2</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#eqmod_small_eq">eqmod_small_eq</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#eqmod_sub">eqmod_sub</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#eqmod_sym">eqmod_sym</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#eqmod_trans">eqmod_trans</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#eqmod_256_unsigned_repr">eqmod_256_unsigned_repr</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#eqmod_65536_unsigned_repr">eqmod_65536_unsigned_repr</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#eqm_add">eqm_add</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#eqm_mult">eqm_mult</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#eqm_neg">eqm_neg</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#eqm_refl">eqm_refl</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#eqm_refl2">eqm_refl2</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#eqm_samerepr">eqm_samerepr</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#eqm_signed_unsigned">eqm_signed_unsigned</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#eqm_small_eq">eqm_small_eq</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#eqm_sub">eqm_sub</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#eqm_sym">eqm_sym</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#eqm_trans">eqm_trans</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#eqm_unsigned_repr">eqm_unsigned_repr</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#eqm_unsigned_repr_l">eqm_unsigned_repr_l</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#eqm_unsigned_repr_r">eqm_unsigned_repr_r</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.RTLtyping.html#equal_eq">equal_eq</a> [in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="lib.Integers.html#equal_on_range">equal_on_range</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.CSEproof.html#equation_evals_to_holds_1">equation_evals_to_holds_1</a> [in <a href="backend.CSEproof.html">backend.CSEproof</a>]<br/>
-<a href="backend.CSEproof.html#equation_evals_to_holds_2">equation_evals_to_holds_2</a> [in <a href="backend.CSEproof.html">backend.CSEproof</a>]<br/>
-<a href="lib.Integers.html#eq_dec">eq_dec</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#eq_false">eq_false</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Ordered.html#eq_refl">eq_refl</a> [in <a href="lib.Ordered.html">lib.Ordered</a>]<br/>
-<a href="lib.Ordered.html#eq_refl">eq_refl</a> [in <a href="lib.Ordered.html">lib.Ordered</a>]<br/>
-<a href="lib.Ordered.html#eq_refl">eq_refl</a> [in <a href="lib.Ordered.html">lib.Ordered</a>]<br/>
-<a href="lib.Integers.html#eq_spec">eq_spec</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Ordered.html#eq_sym">eq_sym</a> [in <a href="lib.Ordered.html">lib.Ordered</a>]<br/>
-<a href="lib.Ordered.html#eq_sym">eq_sym</a> [in <a href="lib.Ordered.html">lib.Ordered</a>]<br/>
-<a href="lib.Integers.html#eq_sym">eq_sym</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Ordered.html#eq_sym">eq_sym</a> [in <a href="lib.Ordered.html">lib.Ordered</a>]<br/>
-<a href="lib.Ordered.html#eq_trans">eq_trans</a> [in <a href="lib.Ordered.html">lib.Ordered</a>]<br/>
-<a href="lib.Ordered.html#eq_trans">eq_trans</a> [in <a href="lib.Ordered.html">lib.Ordered</a>]<br/>
-<a href="lib.Ordered.html#eq_trans">eq_trans</a> [in <a href="lib.Ordered.html">lib.Ordered</a>]<br/>
-<a href="lib.Integers.html#eq_true">eq_true</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.RTLtyping.html#error_inconsistent">error_inconsistent</a> [in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_absfloat">eval_absfloat</a> [in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_add">eval_add</a> [in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_addf">eval_addf</a> [in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_addimm">eval_addimm</a> [in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_addimm_ptr">eval_addimm_ptr</a> [in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_addressing">eval_addressing</a> [in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Op.html#eval_addressing_preserved">eval_addressing_preserved</a> [in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Op.html#eval_addressing_weaken">eval_addressing_weaken</a> [in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_add_ptr">eval_add_ptr</a> [in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_add_ptr_2">eval_add_ptr_2</a> [in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_and">eval_and</a> [in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_andimm">eval_andimm</a> [in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_base_condition_of_expr">eval_base_condition_of_expr</a> [in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_cast16signed">eval_cast16signed</a> [in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_cast16unsigned">eval_cast16unsigned</a> [in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_cast8signed">eval_cast8signed</a> [in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_cast8unsigned">eval_cast8unsigned</a> [in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_cmp">eval_cmp</a> [in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_cmpf">eval_cmpf</a> [in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_cmpu">eval_cmpu</a> [in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_cmp_null_l">eval_cmp_null_l</a> [in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_cmp_null_r">eval_cmp_null_r</a> [in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_cmp_ptr">eval_cmp_ptr</a> [in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Op.html#eval_compare_null_weaken">eval_compare_null_weaken</a> [in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_conditionalexpr_false">eval_conditionalexpr_false</a> [in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_conditionalexpr_true">eval_conditionalexpr_true</a> [in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_condition_of_expr">eval_condition_of_expr</a> [in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Op.html#eval_condition_total_is_bool">eval_condition_total_is_bool</a> [in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Op.html#eval_condition_weaken">eval_condition_weaken</a> [in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_divf">eval_divf</a> [in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_divs">eval_divs</a> [in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_divu">eval_divu</a> [in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_divu_base">eval_divu_base</a> [in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_floatofint">eval_floatofint</a> [in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_floatofintu">eval_floatofintu</a> [in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_intoffloat">eval_intoffloat</a> [in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_lift">eval_lift</a> [in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_lift_expr">eval_lift_expr</a> [in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_load">eval_load</a> [in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_mods">eval_mods</a> [in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_modu">eval_modu</a> [in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_mod_aux">eval_mod_aux</a> [in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_mul">eval_mul</a> [in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_mulf">eval_mulf</a> [in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_mulimm">eval_mulimm</a> [in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_mulimm_base">eval_mulimm_base</a> [in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Op.html#eval_negate_condition">eval_negate_condition</a> [in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_negfloat">eval_negfloat</a> [in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_negint">eval_negint</a> [in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_notbool">eval_notbool</a> [in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_notbool_base">eval_notbool_base</a> [in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_notint">eval_notint</a> [in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Op.html#eval_operation_preserved">eval_operation_preserved</a> [in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Op.html#eval_operation_weaken">eval_operation_weaken</a> [in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_or">eval_or</a> [in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_rolm">eval_rolm</a> [in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_shl">eval_shl</a> [in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_shlimm">eval_shlimm</a> [in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_shr">eval_shr</a> [in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_shru">eval_shru</a> [in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_shruimm">eval_shruimm</a> [in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_singleoffloat">eval_singleoffloat</a> [in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Constpropproof.html#eval_static_condition_correct">eval_static_condition_correct</a> [in <a href="backend.Constpropproof.html">backend.Constpropproof</a>]<br/>
-<a href="backend.Constpropproof.html#eval_static_operation_correct">eval_static_operation_correct</a> [in <a href="backend.Constpropproof.html">backend.Constpropproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_store">eval_store</a> [in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_sub">eval_sub</a> [in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_subf">eval_subf</a> [in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_sub_ptr_int">eval_sub_ptr_int</a> [in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_sub_ptr_ptr">eval_sub_ptr_ptr</a> [in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#eval_xor">eval_xor</a> [in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Tunnelingproof.html#exec_blocks_Bgoto_inv">exec_blocks_Bgoto_inv</a> [in <a href="backend.Tunnelingproof.html">backend.Tunnelingproof</a>]<br/>
-<a href="backend.LTL.html#exec_blocks_extends">exec_blocks_extends</a> [in <a href="backend.LTL.html">backend.LTL</a>]<br/>
-<a href="backend.Linearizeproof.html#exec_blocks_valid_outcome">exec_blocks_valid_outcome</a> [in <a href="backend.Linearizeproof.html">backend.Linearizeproof</a>]<br/>
-<a href="backend.Tunnelingproof.html#exec_block_Bgoto_inv">exec_block_Bgoto_inv</a> [in <a href="backend.Tunnelingproof.html">backend.Tunnelingproof</a>]<br/>
-<a href="backend.PPCgenproof.html#exec_function_body_prop_">exec_function_body_prop_</a> [in <a href="backend.PPCgenproof.html">backend.PPCgenproof</a>]<br/>
-<a href="backend.Machabstr2mach.html#exec_function_equiv">exec_function_equiv</a> [in <a href="backend.Machabstr2mach.html">backend.Machabstr2mach</a>]<br/>
-<a href="backend.PPCgenproof.html#exec_function_prop_">exec_function_prop_</a> [in <a href="backend.PPCgenproof.html">backend.PPCgenproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#exec_ifthenelse_false">exec_ifthenelse_false</a> [in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#exec_ifthenelse_true">exec_ifthenelse_true</a> [in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.RTL.html#exec_Iload'">exec_Iload'</a> [in <a href="backend.RTL.html">backend.RTL</a>]<br/>
-<a href="backend.Tunnelingproof.html#exec_instrs_Bgoto_inv">exec_instrs_Bgoto_inv</a> [in <a href="backend.Tunnelingproof.html">backend.Tunnelingproof</a>]<br/>
-<a href="backend.RTLgenproof1.html#exec_instrs_extends">exec_instrs_extends</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#exec_instrs_extends_rec">exec_instrs_extends_rec</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.Stackingproof.html#exec_instrs_incl">exec_instrs_incl</a> [in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="backend.PPCgenproof.html#exec_instrs_incl">exec_instrs_incl</a> [in <a href="backend.PPCgenproof.html">backend.PPCgenproof</a>]<br/>
-<a href="backend.RTLgenproof1.html#exec_instrs_incr">exec_instrs_incr</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.Machtyping.html#exec_instrs_link_invariant">exec_instrs_link_invariant</a> [in <a href="backend.Machtyping.html">backend.Machtyping</a>]<br/>
-<a href="backend.Allocproof_aux.html#exec_instrs_pmov">exec_instrs_pmov</a> [in <a href="backend.Allocproof_aux.html">backend.Allocproof_aux</a>]<br/>
-<a href="backend.RTL.html#exec_instrs_present">exec_instrs_present</a> [in <a href="backend.RTL.html">backend.RTL</a>]<br/>
-<a href="backend.RTLgenproof1.html#exec_instr_extends">exec_instr_extends</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#exec_instr_extends_rec">exec_instr_extends_rec</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.PPCgenproof.html#exec_instr_incl">exec_instr_incl</a> [in <a href="backend.PPCgenproof.html">backend.PPCgenproof</a>]<br/>
-<a href="backend.Stackingproof.html#exec_instr_incl">exec_instr_incl</a> [in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="backend.RTLgenproof1.html#exec_instr_incr">exec_instr_incr</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#exec_instr_in_s2">exec_instr_in_s2</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.Machtyping.html#exec_instr_link_invariant">exec_instr_link_invariant</a> [in <a href="backend.Machtyping.html">backend.Machtyping</a>]<br/>
-<a href="backend.RTLgenproof1.html#exec_instr_not_halt">exec_instr_not_halt</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTL.html#exec_instr_present">exec_instr_present</a> [in <a href="backend.RTL.html">backend.RTL</a>]<br/>
-<a href="backend.Allocproof_aux.html#exec_instr_update">exec_instr_update</a> [in <a href="backend.Allocproof_aux.html">backend.Allocproof_aux</a>]<br/>
-<a href="backend.RTL.html#exec_Iop'">exec_Iop'</a> [in <a href="backend.RTL.html">backend.RTL</a>]<br/>
-<a href="backend.PPCgenproof.html#exec_Mcall_prop">exec_Mcall_prop</a> [in <a href="backend.PPCgenproof.html">backend.PPCgenproof</a>]<br/>
-<a href="backend.PPCgenproof.html#exec_Mcond_false_prop">exec_Mcond_false_prop</a> [in <a href="backend.PPCgenproof.html">backend.PPCgenproof</a>]<br/>
-<a href="backend.PPCgenproof.html#exec_Mcond_true_prop">exec_Mcond_true_prop</a> [in <a href="backend.PPCgenproof.html">backend.PPCgenproof</a>]<br/>
-<a href="backend.PPCgenproof.html#exec_Mgetparam_prop">exec_Mgetparam_prop</a> [in <a href="backend.PPCgenproof.html">backend.PPCgenproof</a>]<br/>
-<a href="backend.Stackingproof.html#exec_Mgetstack'">exec_Mgetstack'</a> [in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="backend.PPCgenproof.html#exec_Mgetstack_prop">exec_Mgetstack_prop</a> [in <a href="backend.PPCgenproof.html">backend.PPCgenproof</a>]<br/>
-<a href="backend.PPCgenproof.html#exec_Mgoto_prop">exec_Mgoto_prop</a> [in <a href="backend.PPCgenproof.html">backend.PPCgenproof</a>]<br/>
-<a href="backend.PPCgenproof.html#exec_Mlabel_prop">exec_Mlabel_prop</a> [in <a href="backend.PPCgenproof.html">backend.PPCgenproof</a>]<br/>
-<a href="backend.PPCgenproof.html#exec_Mload_prop">exec_Mload_prop</a> [in <a href="backend.PPCgenproof.html">backend.PPCgenproof</a>]<br/>
-<a href="backend.PPCgenproof.html#exec_Mop_prop">exec_Mop_prop</a> [in <a href="backend.PPCgenproof.html">backend.PPCgenproof</a>]<br/>
-<a href="backend.Stackingproof.html#exec_Msetstack'">exec_Msetstack'</a> [in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="backend.PPCgenproof.html#exec_Msetstack_prop">exec_Msetstack_prop</a> [in <a href="backend.PPCgenproof.html">backend.PPCgenproof</a>]<br/>
-<a href="backend.PPCgenproof.html#exec_Mstore_prop">exec_Mstore_prop</a> [in <a href="backend.PPCgenproof.html">backend.PPCgenproof</a>]<br/>
-<a href="backend.Machabstr.html#exec_mutual_induction">exec_mutual_induction</a> [in <a href="backend.Machabstr.html">backend.Machabstr</a>]<br/>
-<a href="backend.PPCgenproof.html#exec_one_prop">exec_one_prop</a> [in <a href="backend.PPCgenproof.html">backend.PPCgenproof</a>]<br/>
-<a href="backend.Machabstr2mach.html#exec_program_equiv">exec_program_equiv</a> [in <a href="backend.Machabstr2mach.html">backend.Machabstr2mach</a>]<br/>
-<a href="backend.PPCgenproof.html#exec_refl_prop">exec_refl_prop</a> [in <a href="backend.PPCgenproof.html">backend.PPCgenproof</a>]<br/>
-<a href="backend.RTL.html#exec_step">exec_step</a> [in <a href="backend.RTL.html">backend.RTL</a>]<br/>
-<a href="backend.PPCgenproof.html#exec_straight_exec_prop">exec_straight_exec_prop</a> [in <a href="backend.PPCgenproof.html">backend.PPCgenproof</a>]<br/>
-<a href="backend.PPCgenproof1.html#exec_straight_one">exec_straight_one</a> [in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.PPCgenproof.html#exec_straight_steps">exec_straight_steps</a> [in <a href="backend.PPCgenproof.html">backend.PPCgenproof</a>]<br/>
-<a href="backend.PPCgenproof.html#exec_straight_steps_1">exec_straight_steps_1</a> [in <a href="backend.PPCgenproof.html">backend.PPCgenproof</a>]<br/>
-<a href="backend.PPCgenproof.html#exec_straight_steps_2">exec_straight_steps_2</a> [in <a href="backend.PPCgenproof.html">backend.PPCgenproof</a>]<br/>
-<a href="backend.PPCgenproof1.html#exec_straight_three">exec_straight_three</a> [in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.PPCgenproof1.html#exec_straight_trans">exec_straight_trans</a> [in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.PPCgenproof1.html#exec_straight_two">exec_straight_two</a> [in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.PPCgenproof.html#exec_trans_prop">exec_trans_prop</a> [in <a href="backend.PPCgenproof.html">backend.PPCgenproof</a>]<br/>
-<a href="backend.RTLgenproof1.html#expr_condexpr_exprlist_ind">expr_condexpr_exprlist_ind</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="lib.Maps.html#exten">exten</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="backend.Mem.html#extends_refl">extends_refl</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#extend_inject_incr">extend_inject_incr</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<br/><br/><a name="lemma_F"></a><h2>F </h2>
-<a href="backend.Globalenvs.html#find_funct_find_funct_ptr">find_funct_find_funct_ptr</a> [in <a href="backend.Globalenvs.html">backend.Globalenvs</a>]<br/>
-<a href="backend.Globalenvs.html#find_funct_inv">find_funct_inv</a> [in <a href="backend.Globalenvs.html">backend.Globalenvs</a>]<br/>
-<a href="backend.Globalenvs.html#find_funct_prop">find_funct_prop</a> [in <a href="backend.Globalenvs.html">backend.Globalenvs</a>]<br/>
-<a href="backend.Globalenvs.html#find_funct_ptr_inv">find_funct_ptr_inv</a> [in <a href="backend.Globalenvs.html">backend.Globalenvs</a>]<br/>
-<a href="backend.Globalenvs.html#find_funct_ptr_prop">find_funct_ptr_prop</a> [in <a href="backend.Globalenvs.html">backend.Globalenvs</a>]<br/>
-<a href="backend.Globalenvs.html#find_funct_ptr_transf">find_funct_ptr_transf</a> [in <a href="backend.Globalenvs.html">backend.Globalenvs</a>]<br/>
-<a href="backend.Globalenvs.html#find_funct_ptr_transf_partial">find_funct_ptr_transf_partial</a> [in <a href="backend.Globalenvs.html">backend.Globalenvs</a>]<br/>
-<a href="backend.Globalenvs.html#find_funct_transf">find_funct_transf</a> [in <a href="backend.Globalenvs.html">backend.Globalenvs</a>]<br/>
-<a href="backend.Globalenvs.html#find_funct_transf_partial">find_funct_transf_partial</a> [in <a href="backend.Globalenvs.html">backend.Globalenvs</a>]<br/>
-<a href="backend.PPCgenproof.html#find_instr_in">find_instr_in</a> [in <a href="backend.PPCgenproof.html">backend.PPCgenproof</a>]<br/>
-<a href="backend.PPCgenproof.html#find_instr_tail">find_instr_tail</a> [in <a href="backend.PPCgenproof.html">backend.PPCgenproof</a>]<br/>
-<a href="backend.Linearizeproof.html#find_label_cleanup_code">find_label_cleanup_code</a> [in <a href="backend.Linearizeproof.html">backend.Linearizeproof</a>]<br/>
-<a href="backend.PPCgenproof.html#find_label_goto_label">find_label_goto_label</a> [in <a href="backend.PPCgenproof.html">backend.PPCgenproof</a>]<br/>
-<a href="backend.Stackingproof.html#find_label_incl">find_label_incl</a> [in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="backend.Linearizeproof.html#find_label_lin">find_label_lin</a> [in <a href="backend.Linearizeproof.html">backend.Linearizeproof</a>]<br/>
-<a href="backend.Linearizeproof.html#find_label_lin_block">find_label_lin_block</a> [in <a href="backend.Linearizeproof.html">backend.Linearizeproof</a>]<br/>
-<a href="backend.Linearizeproof.html#find_label_lin_rec">find_label_lin_rec</a> [in <a href="backend.Linearizeproof.html">backend.Linearizeproof</a>]<br/>
-<a href="backend.Stackingproof.html#find_label_transl_code">find_label_transl_code</a> [in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="backend.Linearizeproof.html#find_label_unique">find_label_unique</a> [in <a href="backend.Linearizeproof.html">backend.Linearizeproof</a>]<br/>
-<a href="backend.RTLgenproof1.html#find_letvar_incr">find_letvar_incr</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#find_letvar_in_map">find_letvar_in_map</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#find_letvar_not_mutated">find_letvar_not_mutated</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#find_letvar_valid">find_letvar_valid</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.CSEproof.html#find_load_correct">find_load_correct</a> [in <a href="backend.CSEproof.html">backend.CSEproof</a>]<br/>
-<a href="backend.CSEproof.html#find_op_correct">find_op_correct</a> [in <a href="backend.CSEproof.html">backend.CSEproof</a>]<br/>
-<a href="backend.CSEproof.html#find_rhs_correct">find_rhs_correct</a> [in <a href="backend.CSEproof.html">backend.CSEproof</a>]<br/>
-<a href="backend.Globalenvs.html#find_symbol_inv">find_symbol_inv</a> [in <a href="backend.Globalenvs.html">backend.Globalenvs</a>]<br/>
-<a href="backend.Globalenvs.html#find_symbol_transf">find_symbol_transf</a> [in <a href="backend.Globalenvs.html">backend.Globalenvs</a>]<br/>
-<a href="backend.Globalenvs.html#find_symbol_transf_partial">find_symbol_transf_partial</a> [in <a href="backend.Globalenvs.html">backend.Globalenvs</a>]<br/>
-<a href="backend.CSEproof.html#find_valnum_rhs_correct">find_valnum_rhs_correct</a> [in <a href="backend.CSEproof.html">backend.CSEproof</a>]<br/>
-<a href="backend.RTLgenproof1.html#find_var_incr">find_var_incr</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#find_var_in_map">find_var_in_map</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#find_var_not_mutated">find_var_not_mutated</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#find_var_valid">find_var_valid</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.Kildall.html#fixpoint_entry">fixpoint_entry</a> [in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Kildall.html#fixpoint_entry">fixpoint_entry</a> [in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Kildall.html#fixpoint_entry">fixpoint_entry</a> [in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Kildall.html#fixpoint_incr">fixpoint_incr</a> [in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Kildall.html#fixpoint_invariant">fixpoint_invariant</a> [in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Kildall.html#fixpoint_solution">fixpoint_solution</a> [in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Kildall.html#fixpoint_solution">fixpoint_solution</a> [in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Kildall.html#fixpoint_solution">fixpoint_solution</a> [in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="lib.Inclusion.html#flatten_aux_valid_A">flatten_aux_valid_A</a> [in <a href="lib.Inclusion.html">lib.Inclusion</a>]<br/>
-<a href="lib.Inclusion.html#flatten_valid_A">flatten_valid_A</a> [in <a href="lib.Inclusion.html">lib.Inclusion</a>]<br/>
-<a href="backend.PPCgenproof1.html#floatcomp_correct">floatcomp_correct</a> [in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.Linearizetyping.html#float_callee_save_bound">float_callee_save_bound</a> [in <a href="backend.Linearizetyping.html">backend.Linearizetyping</a>]<br/>
-<a href="backend.Conventions.html#float_callee_save_norepet">float_callee_save_norepet</a> [in <a href="backend.Conventions.html">backend.Conventions</a>]<br/>
-<a href="backend.Conventions.html#float_callee_save_not_destroyed">float_callee_save_not_destroyed</a> [in <a href="backend.Conventions.html">backend.Conventions</a>]<br/>
-<a href="backend.Conventions.html#float_callee_save_type">float_callee_save_type</a> [in <a href="backend.Conventions.html">backend.Conventions</a>]<br/>
-<a href="backend.Linearizetyping.html#float_local_slot_bound">float_local_slot_bound</a> [in <a href="backend.Linearizetyping.html">backend.Linearizetyping</a>]<br/>
-<a href="lib.Maps.html#fold_spec">fold_spec</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Sets.html#fold_spec">fold_spec</a> [in <a href="lib.Sets.html">lib.Sets</a>]<br/>
-<a href="lib.Sets.html#for_all_spec">for_all_spec</a> [in <a href="lib.Sets.html">lib.Sets</a>]<br/>
-<a href="backend.Parallelmove.html#Fpmov_correct">Fpmov_correct</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#Fpmov_correctMoves">Fpmov_correctMoves</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#Fpmov_correct1">Fpmov_correct1</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#Fpmov_correct2">Fpmov_correct2</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#Fpmov_correct_ext">Fpmov_correct_ext</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#Fpmov_correct_IT3">Fpmov_correct_IT3</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#Fpmov_correct_map">Fpmov_correct_map</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Machabstr2mach.html#frame_match_alloc">frame_match_alloc</a> [in <a href="backend.Machabstr2mach.html">backend.Machabstr2mach</a>]<br/>
-<a href="backend.Machabstr2mach.html#frame_match_exten">frame_match_exten</a> [in <a href="backend.Machabstr2mach.html">backend.Machabstr2mach</a>]<br/>
-<a href="backend.Machabstr2mach.html#frame_match_free">frame_match_free</a> [in <a href="backend.Machabstr2mach.html">backend.Machabstr2mach</a>]<br/>
-<a href="backend.Machabstr2mach.html#frame_match_get_slot">frame_match_get_slot</a> [in <a href="backend.Machabstr2mach.html">backend.Machabstr2mach</a>]<br/>
-<a href="backend.Machabstr2mach.html#frame_match_load">frame_match_load</a> [in <a href="backend.Machabstr2mach.html">backend.Machabstr2mach</a>]<br/>
-<a href="backend.Machabstr2mach.html#frame_match_new">frame_match_new</a> [in <a href="backend.Machabstr2mach.html">backend.Machabstr2mach</a>]<br/>
-<a href="backend.Machabstr2mach.html#frame_match_set_slot">frame_match_set_slot</a> [in <a href="backend.Machabstr2mach.html">backend.Machabstr2mach</a>]<br/>
-<a href="backend.Machabstr2mach.html#frame_match_store">frame_match_store</a> [in <a href="backend.Machabstr2mach.html">backend.Machabstr2mach</a>]<br/>
-<a href="backend.Machabstr2mach.html#frame_match_store_ok">frame_match_store_ok</a> [in <a href="backend.Machabstr2mach.html">backend.Machabstr2mach</a>]<br/>
-<a href="backend.Machabstr2mach.html#frame_match_store_stack_other">frame_match_store_stack_other</a> [in <a href="backend.Machabstr2mach.html">backend.Machabstr2mach</a>]<br/>
-<a href="backend.Mem.html#free_empty_bounds">free_empty_bounds</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#free_extends">free_extends</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#free_first_inject">free_first_inject</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#free_first_list_inject">free_first_list_inject</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#free_inject">free_inject</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#free_snd_inject">free_snd_inject</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.PPC.html#freg_eq">freg_eq</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPCgenproof1.html#freg_of_is_data_reg">freg_of_is_data_reg</a> [in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.PPCgenproof1.html#freg_of_not_FPR13">freg_of_not_FPR13</a> [in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.PPCgenproof1.html#freg_val">freg_val</a> [in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.Mem.html#fresh_block_alloc">fresh_block_alloc</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Globalenvs.html#functions_globalenv">functions_globalenv</a> [in <a href="backend.Globalenvs.html">backend.Globalenvs</a>]<br/>
-<a href="backend.Constpropproof.html#functions_translated">functions_translated</a> [in <a href="backend.Constpropproof.html">backend.Constpropproof</a>]<br/>
-<a href="backend.Tunnelingproof.html#functions_translated">functions_translated</a> [in <a href="backend.Tunnelingproof.html">backend.Tunnelingproof</a>]<br/>
-<a href="backend.PPCgenproof.html#functions_translated">functions_translated</a> [in <a href="backend.PPCgenproof.html">backend.PPCgenproof</a>]<br/>
-<a href="backend.Allocproof.html#functions_translated">functions_translated</a> [in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.Linearizeproof.html#functions_translated">functions_translated</a> [in <a href="backend.Linearizeproof.html">backend.Linearizeproof</a>]<br/>
-<a href="backend.Stackingproof.html#functions_translated">functions_translated</a> [in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="backend.CSEproof.html#functions_translated">functions_translated</a> [in <a href="backend.CSEproof.html">backend.CSEproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#functions_translated">functions_translated</a> [in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.RTLgenproof.html#functions_translated">functions_translated</a> [in <a href="backend.RTLgenproof.html">backend.RTLgenproof</a>]<br/>
-<a href="backend.PPCgenproof.html#functions_translated_no_overflow">functions_translated_no_overflow</a> [in <a href="backend.PPCgenproof.html">backend.PPCgenproof</a>]<br/>
-<a href="backend.PPCgenproof.html#functions_translated_2">functions_translated_2</a> [in <a href="backend.PPCgenproof.html">backend.PPCgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#function_entry_ok">function_entry_ok</a> [in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Linearizeproof.html#function_ptr_translated">function_ptr_translated</a> [in <a href="backend.Linearizeproof.html">backend.Linearizeproof</a>]<br/>
-<a href="backend.Allocproof.html#function_ptr_translated">function_ptr_translated</a> [in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.Stackingproof.html#function_ptr_translated">function_ptr_translated</a> [in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#function_ptr_translated">function_ptr_translated</a> [in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.RTLgenproof.html#function_ptr_translated">function_ptr_translated</a> [in <a href="backend.RTLgenproof.html">backend.RTLgenproof</a>]<br/>
-<a href="backend.Constpropproof.html#function_ptr_translated">function_ptr_translated</a> [in <a href="backend.Constpropproof.html">backend.Constpropproof</a>]<br/>
-<a href="backend.Tunnelingproof.html#function_ptr_translated">function_ptr_translated</a> [in <a href="backend.Tunnelingproof.html">backend.Tunnelingproof</a>]<br/>
-<a href="backend.CSEproof.html#funct_ptr_translated">funct_ptr_translated</a> [in <a href="backend.CSEproof.html">backend.CSEproof</a>]<br/>
-<a href="backend.Parallelmove.html#f2ind">f2ind</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#f2ind'">f2ind'</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<br/><br/><a name="lemma_G"></a><h2>G </h2>
-<a href="lib.Maps.html#gcombine">gcombine</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#gempty">gempty</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="backend.Parallelmove.html#getdst_add">getdst_add</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#getdst_app">getdst_app</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Alloctyping_aux.html#getdst_f">getdst_f</a> [in <a href="backend.Alloctyping_aux.html">backend.Alloctyping_aux</a>]<br/>
-<a href="backend.Allocproof_aux.html#getdst_lists2moves">getdst_lists2moves</a> [in <a href="backend.Allocproof_aux.html">backend.Allocproof_aux</a>]<br/>
-<a href="backend.Parallelmove.html#getdst_map">getdst_map</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Mem.html#getN_agree">getN_agree</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#getN_init">getN_init</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#getN_inject">getN_inject</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#getN_setN_mismatch">getN_setN_mismatch</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#getN_setN_other">getN_setN_other</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#getN_setN_overlap">getN_setN_overlap</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#getN_setN_same">getN_setN_same</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Allocproof_aux.html#getsrcdst_app">getsrcdst_app</a> [in <a href="backend.Allocproof_aux.html">backend.Allocproof_aux</a>]<br/>
-<a href="backend.Parallelmove.html#getsrc_add">getsrc_add</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#getsrc_add1">getsrc_add1</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#getsrc_app">getsrc_app</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Alloctyping_aux.html#getsrc_f">getsrc_f</a> [in <a href="backend.Alloctyping_aux.html">backend.Alloctyping_aux</a>]<br/>
-<a href="backend.Parallelmove.html#getsrc_map">getsrc_map</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.RTLtyping.html#get_add_1">get_add_1</a> [in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.RTLtyping.html#get_add_2">get_add_2</a> [in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="lib.Lattice.html#get_bot">get_bot</a> [in <a href="lib.Lattice.html">lib.Lattice</a>]<br/>
-<a href="backend.RTLtyping.html#get_empty">get_empty</a> [in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.Parallelmove.html#get_noWrite">get_noWrite</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#get_pexec_id_noWrite">get_pexec_id_noWrite</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Stackingproof.html#get_slot_index">get_slot_index</a> [in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="backend.Stackingproof.html#get_slot_ok">get_slot_ok</a> [in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="lib.Lattice.html#get_top">get_top</a> [in <a href="lib.Lattice.html">lib.Lattice</a>]<br/>
-<a href="backend.Parallelmove.html#get_update">get_update</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#get_update_diff">get_update_diff</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#get_update_id">get_update_id</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#get_update_ndiff">get_update_ndiff</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="lib.Maps.html#get_xget_h">get_xget_h</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Lattice.html#ge_bot">ge_bot</a> [in <a href="lib.Lattice.html">lib.Lattice</a>]<br/>
-<a href="lib.Lattice.html#ge_bot">ge_bot</a> [in <a href="lib.Lattice.html">lib.Lattice</a>]<br/>
-<a href="lib.Sets.html#ge_bot">ge_bot</a> [in <a href="lib.Sets.html">lib.Sets</a>]<br/>
-<a href="lib.Lattice.html#ge_bot">ge_bot</a> [in <a href="lib.Lattice.html">lib.Lattice</a>]<br/>
-<a href="backend.Constprop.html#ge_bot">ge_bot</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="lib.Lattice.html#ge_lub_left">ge_lub_left</a> [in <a href="lib.Lattice.html">lib.Lattice</a>]<br/>
-<a href="lib.Sets.html#ge_lub_left">ge_lub_left</a> [in <a href="lib.Sets.html">lib.Sets</a>]<br/>
-<a href="backend.Constprop.html#ge_lub_left">ge_lub_left</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="lib.Lattice.html#ge_lub_left">ge_lub_left</a> [in <a href="lib.Lattice.html">lib.Lattice</a>]<br/>
-<a href="lib.Lattice.html#ge_lub_left">ge_lub_left</a> [in <a href="lib.Lattice.html">lib.Lattice</a>]<br/>
-<a href="lib.Sets.html#ge_lub_right">ge_lub_right</a> [in <a href="lib.Sets.html">lib.Sets</a>]<br/>
-<a href="lib.Lattice.html#ge_refl">ge_refl</a> [in <a href="lib.Lattice.html">lib.Lattice</a>]<br/>
-<a href="lib.Sets.html#ge_refl">ge_refl</a> [in <a href="lib.Sets.html">lib.Sets</a>]<br/>
-<a href="lib.Lattice.html#ge_refl">ge_refl</a> [in <a href="lib.Lattice.html">lib.Lattice</a>]<br/>
-<a href="lib.Lattice.html#ge_refl">ge_refl</a> [in <a href="lib.Lattice.html">lib.Lattice</a>]<br/>
-<a href="backend.Constprop.html#ge_refl">ge_refl</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="lib.Lattice.html#ge_top">ge_top</a> [in <a href="lib.Lattice.html">lib.Lattice</a>]<br/>
-<a href="backend.Constprop.html#ge_top">ge_top</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="lib.Lattice.html#ge_top">ge_top</a> [in <a href="lib.Lattice.html">lib.Lattice</a>]<br/>
-<a href="lib.Lattice.html#ge_top">ge_top</a> [in <a href="lib.Lattice.html">lib.Lattice</a>]<br/>
-<a href="lib.Lattice.html#ge_trans">ge_trans</a> [in <a href="lib.Lattice.html">lib.Lattice</a>]<br/>
-<a href="backend.Constprop.html#ge_trans">ge_trans</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="lib.Sets.html#ge_trans">ge_trans</a> [in <a href="lib.Sets.html">lib.Sets</a>]<br/>
-<a href="lib.Lattice.html#ge_trans">ge_trans</a> [in <a href="lib.Lattice.html">lib.Lattice</a>]<br/>
-<a href="lib.Lattice.html#ge_trans">ge_trans</a> [in <a href="lib.Lattice.html">lib.Lattice</a>]<br/>
-<a href="lib.Maps.html#gi">gi</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#gi">gi</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#gi">gi</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#gleaf">gleaf</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#gmap">gmap</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#gmap">gmap</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#gmap">gmap</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#gmap">gmap</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="backend.PPCgenproof1.html#gpr_or_zero_not_zero">gpr_or_zero_not_zero</a> [in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.PPCgenproof1.html#gpr_or_zero_zero">gpr_or_zero_zero</a> [in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.Coloringproof.html#graph_incl_refl">graph_incl_refl</a> [in <a href="backend.Coloringproof.html">backend.Coloringproof</a>]<br/>
-<a href="backend.InterfGraph.html#graph_incl_trans">graph_incl_trans</a> [in <a href="backend.InterfGraph.html">backend.InterfGraph</a>]<br/>
-<a href="lib.Maps.html#gro">gro</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#grs">grs</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#gsident">gsident</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#gsident">gsident</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#gsident">gsident</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#gso">gso</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="backend.Locations.html#gso">gso</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="lib.Maps.html#gso">gso</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#gso">gso</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Lattice.html#gso">gso</a> [in <a href="lib.Lattice.html">lib.Lattice</a>]<br/>
-<a href="lib.Maps.html#gso">gso</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#gss">gss</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#gss">gss</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="backend.Locations.html#gss">gss</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="lib.Maps.html#gss">gss</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Lattice.html#gss">gss</a> [in <a href="lib.Lattice.html">lib.Lattice</a>]<br/>
-<a href="lib.Maps.html#gss">gss</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#gsspec">gsspec</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#gsspec">gsspec</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#gsspec">gsspec</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#gsspec">gsspec</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<br/><br/><a name="lemma_H"></a><h2>H </h2>
-<a href="backend.Mem.html#high_bound_alloc">high_bound_alloc</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#high_bound_free">high_bound_free</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#high_bound_store">high_bound_store</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.PPCgenproof1.html#high_half_signed_zero">high_half_signed_zero</a> [in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.PPCgenproof1.html#high_half_unsigned_zero">high_half_unsigned_zero</a> [in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<br/><br/><a name="lemma_I"></a><h2>I </h2>
-<a href="lib.union_find.html#identify_aux_decomp">identify_aux_decomp</a> [in <a href="lib.union_find.html">lib.union_find</a>]<br/>
-<a href="lib.union_find.html#identify_base_a_maps_to_b">identify_base_a_maps_to_b</a> [in <a href="lib.union_find.html">lib.union_find</a>]<br/>
-<a href="lib.union_find.html#identify_base_b_canon">identify_base_b_canon</a> [in <a href="lib.union_find.html">lib.union_find</a>]<br/>
-<a href="lib.union_find.html#identify_base_order_wf">identify_base_order_wf</a> [in <a href="lib.union_find.html">lib.union_find</a>]<br/>
-<a href="lib.union_find.html#identify_base_repr">identify_base_repr</a> [in <a href="lib.union_find.html">lib.union_find</a>]<br/>
-<a href="lib.union_find.html#identify_base_repr_order">identify_base_repr_order</a> [in <a href="lib.union_find.html">lib.union_find</a>]<br/>
-<a href="lib.union_find.html#identify_base_sameclass_1">identify_base_sameclass_1</a> [in <a href="lib.union_find.html">lib.union_find</a>]<br/>
-<a href="lib.union_find.html#identify_base_sameclass_2">identify_base_sameclass_2</a> [in <a href="lib.union_find.html">lib.union_find</a>]<br/>
-<a href="backend.RTLtyping.html#included_consistent">included_consistent</a> [in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.RTLtyping.html#included_identify">included_identify</a> [in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.RTLtyping.html#included_mapped">included_mapped</a> [in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.RTLtyping.html#included_mapped_forall">included_mapped_forall</a> [in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.RTLtyping.html#included_refl">included_refl</a> [in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.RTLtyping.html#included_trans">included_trans</a> [in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="lib.Inclusion.html#inclusion_theorem">inclusion_theorem</a> [in <a href="lib.Inclusion.html">lib.Inclusion</a>]<br/>
-<a href="lib.Coqlib.html#incl_app_inv_l">incl_app_inv_l</a> [in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#incl_app_inv_r">incl_app_inv_r</a> [in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#incl_cons_inv">incl_cons_inv</a> [in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="backend.Alloctyping_aux.html#incl_dst">incl_dst</a> [in <a href="backend.Alloctyping_aux.html">backend.Alloctyping_aux</a>]<br/>
-<a href="backend.Machtyping.html#incl_find_label">incl_find_label</a> [in <a href="backend.Machtyping.html">backend.Machtyping</a>]<br/>
-<a href="backend.Alloctyping_aux.html#incl_nil">incl_nil</a> [in <a href="backend.Alloctyping_aux.html">backend.Alloctyping_aux</a>]<br/>
-<a href="lib.Coqlib.html#incl_same_head">incl_same_head</a> [in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="backend.Alloctyping_aux.html#incl_src">incl_src</a> [in <a href="backend.Alloctyping_aux.html">backend.Alloctyping_aux</a>]<br/>
-<a href="backend.Stackingproof.html#index_arg_valid">index_arg_valid</a> [in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="backend.Conventions.html#index_float_callee_save_inj">index_float_callee_save_inj</a> [in <a href="backend.Conventions.html">backend.Conventions</a>]<br/>
-<a href="backend.Conventions.html#index_float_callee_save_pos">index_float_callee_save_pos</a> [in <a href="backend.Conventions.html">backend.Conventions</a>]<br/>
-<a href="backend.Conventions.html#index_float_callee_save_pos2">index_float_callee_save_pos2</a> [in <a href="backend.Conventions.html">backend.Conventions</a>]<br/>
-<a href="lib.Maps.html#index_inj">index_inj</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="backend.Locations.html#index_inj">index_inj</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="lib.Maps.html#index_inj">index_inj</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="backend.Conventions.html#index_int_callee_save_inj">index_int_callee_save_inj</a> [in <a href="backend.Conventions.html">backend.Conventions</a>]<br/>
-<a href="backend.Conventions.html#index_int_callee_save_pos">index_int_callee_save_pos</a> [in <a href="backend.Conventions.html">backend.Conventions</a>]<br/>
-<a href="backend.Conventions.html#index_int_callee_save_pos2">index_int_callee_save_pos2</a> [in <a href="backend.Conventions.html">backend.Conventions</a>]<br/>
-<a href="backend.Stackingproof.html#index_local_valid">index_local_valid</a> [in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="backend.Stackingproof.html#index_saved_float_valid">index_saved_float_valid</a> [in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="backend.Stackingproof.html#index_saved_int_valid">index_saved_int_valid</a> [in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="backend.Stackingproof.html#index_val_init_frame">index_val_init_frame</a> [in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="backend.Parallelmove.html#Indst_noOverlap_aux">Indst_noOverlap_aux</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#Ingetsrc_swap">Ingetsrc_swap</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#Ingetsrc_swap2">Ingetsrc_swap2</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Kildall.html#initial_state_invariant">initial_state_invariant</a> [in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Globalenvs.html#initmem_nullptr">initmem_nullptr</a> [in <a href="backend.Globalenvs.html">backend.Globalenvs</a>]<br/>
-<a href="backend.Globalenvs.html#initmem_undef">initmem_undef</a> [in <a href="backend.Globalenvs.html">backend.Globalenvs</a>]<br/>
-<a href="backend.RTLgenproof1.html#init_mapping_wf">init_mapping_wf</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.Globalenvs.html#init_mem_transf">init_mem_transf</a> [in <a href="backend.Globalenvs.html">backend.Globalenvs</a>]<br/>
-<a href="backend.Globalenvs.html#init_mem_transf_partial">init_mem_transf_partial</a> [in <a href="backend.Globalenvs.html">backend.Globalenvs</a>]<br/>
-<a href="backend.RTLgen.html#init_state_wf">init_state_wf</a> [in <a href="backend.RTLgen.html">backend.RTLgen</a>]<br/>
-<a href="backend.Mem.html#inject_incr_refl">inject_incr_refl</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#inject_incr_trans">inject_incr_trans</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="lib.Inclusion.html#insert_bin_included">insert_bin_included</a> [in <a href="lib.Inclusion.html">lib.Inclusion</a>]<br/>
-<a href="backend.Cmconstrproof.html#insert_lenv_lookup1">insert_lenv_lookup1</a> [in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#insert_lenv_lookup2">insert_lenv_lookup2</a> [in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.RTLgenproof1.html#instr_at_incr">instr_at_incr</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.Coloringproof.html#interfere_incl">interfere_incl</a> [in <a href="backend.Coloringproof.html">backend.Coloringproof</a>]<br/>
-<a href="backend.Coloringproof.html#interfere_mreg_incl">interfere_mreg_incl</a> [in <a href="backend.Coloringproof.html">backend.Coloringproof</a>]<br/>
-<a href="backend.InterfGraph.html#interfere_sym">interfere_sym</a> [in <a href="backend.InterfGraph.html">backend.InterfGraph</a>]<br/>
-<a href="backend.Coloringproof.html#interf_graph_correct_1">interf_graph_correct_1</a> [in <a href="backend.Coloringproof.html">backend.Coloringproof</a>]<br/>
-<a href="backend.Coloringproof.html#interf_graph_correct_2">interf_graph_correct_2</a> [in <a href="backend.Coloringproof.html">backend.Coloringproof</a>]<br/>
-<a href="backend.Coloringproof.html#interf_graph_correct_3">interf_graph_correct_3</a> [in <a href="backend.Coloringproof.html">backend.Coloringproof</a>]<br/>
-<a href="backend.Constpropproof.html#intval_correct">intval_correct</a> [in <a href="backend.Constpropproof.html">backend.Constpropproof</a>]<br/>
-<a href="backend.Machabstr2mach.html#int_add_no_overflow">int_add_no_overflow</a> [in <a href="backend.Machabstr2mach.html">backend.Machabstr2mach</a>]<br/>
-<a href="backend.Linearizetyping.html#int_callee_save_bound">int_callee_save_bound</a> [in <a href="backend.Linearizetyping.html">backend.Linearizetyping</a>]<br/>
-<a href="backend.Conventions.html#int_callee_save_norepet">int_callee_save_norepet</a> [in <a href="backend.Conventions.html">backend.Conventions</a>]<br/>
-<a href="backend.Conventions.html#int_callee_save_not_destroyed">int_callee_save_not_destroyed</a> [in <a href="backend.Conventions.html">backend.Conventions</a>]<br/>
-<a href="backend.Conventions.html#int_callee_save_type">int_callee_save_type</a> [in <a href="backend.Conventions.html">backend.Conventions</a>]<br/>
-<a href="backend.Conventions.html#int_float_callee_save_disjoint">int_float_callee_save_disjoint</a> [in <a href="backend.Conventions.html">backend.Conventions</a>]<br/>
-<a href="backend.Linearizetyping.html#int_local_slot_bound">int_local_slot_bound</a> [in <a href="backend.Linearizetyping.html">backend.Linearizetyping</a>]<br/>
-<a href="backend.Cmconstrproof.html#inv_eval_Eop_0">inv_eval_Eop_0</a> [in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#inv_eval_Eop_1">inv_eval_Eop_1</a> [in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#inv_eval_Eop_2">inv_eval_Eop_2</a> [in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Mem.html#in_bounds_exten">in_bounds_exten</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#in_bounds_holds">in_bounds_holds</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#in_bounds_inject">in_bounds_inject</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Allocproof_aux.html#in_cons_noteq">in_cons_noteq</a> [in <a href="backend.Allocproof_aux.html">backend.Allocproof_aux</a>]<br/>
-<a href="backend.Kildall.html#in_incr_refl">in_incr_refl</a> [in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Kildall.html#in_incr_trans">in_incr_trans</a> [in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Parallelmove.html#In_Indst">In_Indst</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Alloctyping_aux.html#in_move__in_srcdst">in_move__in_srcdst</a> [in <a href="backend.Alloctyping_aux.html">backend.Alloctyping_aux</a>]<br/>
-<a href="backend.Allocproof_aux.html#In_norepet">In_norepet</a> [in <a href="backend.Allocproof_aux.html">backend.Allocproof_aux</a>]<br/>
-<a href="backend.Locations.html#in_notin_diff">in_notin_diff</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Parallelmove.html#In_noTmp_notempo">In_noTmp_notempo</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="lib.Inclusion.html#in_or_insert_bin">in_or_insert_bin</a> [in <a href="lib.Inclusion.html">lib.Inclusion</a>]<br/>
-<a href="backend.Machabstr2mach.html#in_or_notin_callstack">in_or_notin_callstack</a> [in <a href="backend.Machabstr2mach.html">backend.Machabstr2mach</a>]<br/>
-<a href="lib.Inclusion.html#In_permute_app_head">In_permute_app_head</a> [in <a href="lib.Inclusion.html">lib.Inclusion</a>]<br/>
-<a href="lib.Integers.html#in_range_range">in_range_range</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Inclusion.html#in_remove_head">in_remove_head</a> [in <a href="lib.Inclusion.html">lib.Inclusion</a>]<br/>
-<a href="backend.Parallelmove.html#In_SD_diff">In_SD_diff</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#In_SD_diff'">In_SD_diff'</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#In_SD_no_o">In_SD_no_o</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Alloctyping_aux.html#in_split_move">in_split_move</a> [in <a href="backend.Alloctyping_aux.html">backend.Alloctyping_aux</a>]<br/>
-<a href="lib.Maps.html#in_xelements">in_xelements</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#in_xkeys">in_xkeys</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="backend.PPC.html#ireg_eq">ireg_eq</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPCgenproof1.html#ireg_of_is_data_reg">ireg_of_is_data_reg</a> [in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.PPCgenproof1.html#ireg_of_not_GPR1">ireg_of_not_GPR1</a> [in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.PPCgenproof1.html#ireg_of_not_GPR2">ireg_of_not_GPR2</a> [in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.PPCgenproof1.html#ireg_val">ireg_val</a> [in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.Values.html#isfalse_not_istrue">isfalse_not_istrue</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Values.html#istrue_not_isfalse">istrue_not_isfalse</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Tunnelingproof.html#is_goto_block_correct">is_goto_block_correct</a> [in <a href="backend.Tunnelingproof.html">backend.Tunnelingproof</a>]<br/>
-<a href="backend.PPC.html#is_label_correct">is_label_correct</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.Mach.html#is_label_correct">is_label_correct</a> [in <a href="backend.Mach.html">backend.Mach</a>]<br/>
-<a href="backend.Linear.html#is_label_correct">is_label_correct</a> [in <a href="backend.Linear.html">backend.Linear</a>]<br/>
-<a href="backend.Op.html#is_move_operation_correct">is_move_operation_correct</a> [in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="lib.Integers.html#is_power2_correct">is_power2_correct</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#is_power2_range">is_power2_range</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#is_power2_rng">is_power2_rng</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Linearizeproof.html#is_tail_cons_left">is_tail_cons_left</a> [in <a href="backend.Linearizeproof.html">backend.Linearizeproof</a>]<br/>
-<a href="backend.Linearizeproof.html#is_tail_exec_instr">is_tail_exec_instr</a> [in <a href="backend.Linearizeproof.html">backend.Linearizeproof</a>]<br/>
-<a href="backend.Linearizeproof.html#is_tail_exec_instrs">is_tail_exec_instrs</a> [in <a href="backend.Linearizeproof.html">backend.Linearizeproof</a>]<br/>
-<a href="backend.Linearizeproof.html#is_tail_find_label">is_tail_find_label</a> [in <a href="backend.Linearizeproof.html">backend.Linearizeproof</a>]<br/>
-<a href="backend.Linearizeproof.html#is_tail_in">is_tail_in</a> [in <a href="backend.Linearizeproof.html">backend.Linearizeproof</a>]<br/>
-<a href="backend.Kildall.html#iterate_base">iterate_base</a> [in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Kildall.html#iterate_incr">iterate_incr</a> [in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Kildall.html#iterate_solution">iterate_solution</a> [in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Kildall.html#iterate_step">iterate_step</a> [in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<br/><br/><a name="lemma_K"></a><h2>K </h2>
-<a href="backend.CSEproof.html#kill_load_eqs_incl">kill_load_eqs_incl</a> [in <a href="backend.CSEproof.html">backend.CSEproof</a>]<br/>
-<a href="backend.CSEproof.html#kill_load_eqs_ops">kill_load_eqs_ops</a> [in <a href="backend.CSEproof.html">backend.CSEproof</a>]<br/>
-<a href="backend.CSEproof.html#kill_load_satisfiable">kill_load_satisfiable</a> [in <a href="backend.CSEproof.html">backend.CSEproof</a>]<br/>
-<br/><br/><a name="lemma_L"></a><h2>L </h2>
-<a href="backend.Linearizeproof.html#label_in_lin_block">label_in_lin_block</a> [in <a href="backend.Linearizeproof.html">backend.Linearizeproof</a>]<br/>
-<a href="backend.Linearizeproof.html#label_in_lin_rec">label_in_lin_rec</a> [in <a href="backend.Linearizeproof.html">backend.Linearizeproof</a>]<br/>
-<a href="backend.PPCgenproof.html#label_pos_code_tail">label_pos_code_tail</a> [in <a href="backend.PPCgenproof.html">backend.PPCgenproof</a>]<br/>
-<a href="backend.Parallelmove.html#last_app">last_app</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#last_cons">last_cons</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#last_replace">last_replace</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Allocproof.html#length_addr_args">length_addr_args</a> [in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.Parallelmove.html#length_app">length_app</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Allocproof.html#length_cond_args">length_cond_args</a> [in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.Allocproof.html#length_op_args">length_op_args</a> [in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.Parallelmove.html#length_replace">length_replace</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.RTLtyping.html#let_fold_args_res">let_fold_args_res</a> [in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.Linearizetyping.html#linearize_block_incl">linearize_block_incl</a> [in <a href="backend.Linearizetyping.html">backend.Linearizetyping</a>]<br/>
-<a href="lib.Coqlib.html#list_append_map">list_append_map</a> [in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#list_disjoint_cons_left">list_disjoint_cons_left</a> [in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#list_disjoint_cons_right">list_disjoint_cons_right</a> [in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#list_disjoint_notin">list_disjoint_notin</a> [in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#list_disjoint_sym">list_disjoint_sym</a> [in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#list_forall2_imply">list_forall2_imply</a> [in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#list_in_map_inv">list_in_map_inv</a> [in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#list_length_map">list_length_map</a> [in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#list_map_compose">list_map_compose</a> [in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#list_map_exten">list_map_exten</a> [in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#list_map_norepet">list_map_norepet</a> [in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#list_map_nth">list_map_nth</a> [in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#list_norepet_append">list_norepet_append</a> [in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#list_norepet_append_left">list_norepet_append_left</a> [in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#list_norepet_append_right">list_norepet_append_right</a> [in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#list_norepet_dec">list_norepet_dec</a> [in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="backend.PPCgenproof1.html#loadimm_correct">loadimm_correct</a> [in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.PPCgenproof1.html#loadind_aux_correct">loadind_aux_correct</a> [in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.PPCgenproof1.html#loadind_correct">loadind_correct</a> [in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.Mem.html#loadv_inject">loadv_inject</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.PPCgenproof.html#loadv_8_signed_unsigned">loadv_8_signed_unsigned</a> [in <a href="backend.PPCgenproof.html">backend.PPCgenproof</a>]<br/>
-<a href="backend.Mem.html#load_agree">load_agree</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#load_alloc_other">load_alloc_other</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#load_alloc_same">load_alloc_same</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#load_contentmap_agree">load_contentmap_agree</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#load_contents_init">load_contents_init</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#load_contents_inject">load_contents_inject</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#load_extends">load_extends</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#load_free">load_free</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Cminorgenproof.html#load_freelist">load_freelist</a> [in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#load_from_alloc_is_undef">load_from_alloc_is_undef</a> [in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Mem.html#load_inject">load_inject</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#load_inv">load_inv</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#load_in_bounds">load_in_bounds</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Cminorgenproof.html#load_result_idem">load_result_idem</a> [in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Mem.html#load_result_inject">load_result_inject</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Cminorgenproof.html#load_result_normalized">load_result_normalized</a> [in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Machabstr2mach.html#load_result_ty">load_result_ty</a> [in <a href="backend.Machabstr2mach.html">backend.Machabstr2mach</a>]<br/>
-<a href="backend.Mem.html#load_store_contents_mismatch">load_store_contents_mismatch</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#load_store_contents_other">load_store_contents_other</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#load_store_contents_overlap">load_store_contents_overlap</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#load_store_contents_same">load_store_contents_same</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#load_store_other">load_store_other</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#load_store_same">load_store_same</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Conventions.html#locs_acceptable_disj_temporaries">locs_acceptable_disj_temporaries</a> [in <a href="backend.Conventions.html">backend.Conventions</a>]<br/>
-<a href="backend.Allocproof.html#loc_acceptable_noteq_diff">loc_acceptable_noteq_diff</a> [in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.Allocproof.html#loc_acceptable_notin_notin">loc_acceptable_notin_notin</a> [in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.Conventions.html#loc_arguments_acceptable">loc_arguments_acceptable</a> [in <a href="backend.Conventions.html">backend.Conventions</a>]<br/>
-<a href="backend.Conventions.html#loc_arguments_bounded">loc_arguments_bounded</a> [in <a href="backend.Conventions.html">backend.Conventions</a>]<br/>
-<a href="backend.Conventions.html#loc_arguments_length">loc_arguments_length</a> [in <a href="backend.Conventions.html">backend.Conventions</a>]<br/>
-<a href="backend.Conventions.html#loc_arguments_norepet">loc_arguments_norepet</a> [in <a href="backend.Conventions.html">backend.Conventions</a>]<br/>
-<a href="backend.Conventions.html#loc_arguments_not_temporaries">loc_arguments_not_temporaries</a> [in <a href="backend.Conventions.html">backend.Conventions</a>]<br/>
-<a href="backend.Conventions.html#loc_arguments_type">loc_arguments_type</a> [in <a href="backend.Conventions.html">backend.Conventions</a>]<br/>
-<a href="backend.Coloringproof.html#loc_is_acceptable_correct">loc_is_acceptable_correct</a> [in <a href="backend.Coloringproof.html">backend.Coloringproof</a>]<br/>
-<a href="backend.Conventions.html#loc_parameters_not_temporaries">loc_parameters_not_temporaries</a> [in <a href="backend.Conventions.html">backend.Conventions</a>]<br/>
-<a href="backend.Conventions.html#loc_parameters_type">loc_parameters_type</a> [in <a href="backend.Conventions.html">backend.Conventions</a>]<br/>
-<a href="backend.Conventions.html#loc_result_acceptable">loc_result_acceptable</a> [in <a href="backend.Conventions.html">backend.Conventions</a>]<br/>
-<a href="backend.Conventions.html#loc_result_type">loc_result_type</a> [in <a href="backend.Conventions.html">backend.Conventions</a>]<br/>
-<a href="backend.Mem.html#low_bound_alloc">low_bound_alloc</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#low_bound_free">low_bound_free</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#low_bound_store">low_bound_store</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.PPCgenproof1.html#low_high_s">low_high_s</a> [in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.PPCgenproof1.html#low_high_u">low_high_u</a> [in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.PPCgenproof1.html#low_high_u_xor">low_high_u_xor</a> [in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="lib.Ordered.html#lt_not_eq">lt_not_eq</a> [in <a href="lib.Ordered.html">lib.Ordered</a>]<br/>
-<a href="lib.Ordered.html#lt_not_eq">lt_not_eq</a> [in <a href="lib.Ordered.html">lib.Ordered</a>]<br/>
-<a href="lib.Ordered.html#lt_not_eq">lt_not_eq</a> [in <a href="lib.Ordered.html">lib.Ordered</a>]<br/>
-<a href="lib.Ordered.html#lt_trans">lt_trans</a> [in <a href="lib.Ordered.html">lib.Ordered</a>]<br/>
-<a href="lib.Ordered.html#lt_trans">lt_trans</a> [in <a href="lib.Ordered.html">lib.Ordered</a>]<br/>
-<a href="lib.Ordered.html#lt_trans">lt_trans</a> [in <a href="lib.Ordered.html">lib.Ordered</a>]<br/>
-<a href="lib.Lattice.html#lub_commut">lub_commut</a> [in <a href="lib.Lattice.html">lib.Lattice</a>]<br/>
-<a href="backend.Constprop.html#lub_commut">lub_commut</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="lib.Lattice.html#lub_commut">lub_commut</a> [in <a href="lib.Lattice.html">lib.Lattice</a>]<br/>
-<a href="lib.Sets.html#lub_commut">lub_commut</a> [in <a href="lib.Sets.html">lib.Sets</a>]<br/>
-<a href="lib.Lattice.html#lub_commut">lub_commut</a> [in <a href="lib.Lattice.html">lib.Lattice</a>]<br/>
-<br/><br/><a name="lemma_M"></a><h2>M </h2>
-<a href="backend.Constpropproof.html#make_addimm_correct">make_addimm_correct</a> [in <a href="backend.Constpropproof.html">backend.Constpropproof</a>]<br/>
-<a href="backend.Constpropproof.html#make_andimm_correct">make_andimm_correct</a> [in <a href="backend.Constpropproof.html">backend.Constpropproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#make_cast_correct">make_cast_correct</a> [in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#make_load_correct">make_load_correct</a> [in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Constpropproof.html#make_mulimm_correct">make_mulimm_correct</a> [in <a href="backend.Constpropproof.html">backend.Constpropproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#make_op_correct">make_op_correct</a> [in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Constpropproof.html#make_orimm_correct">make_orimm_correct</a> [in <a href="backend.Constpropproof.html">backend.Constpropproof</a>]<br/>
-<a href="backend.Kildall.html#make_predecessors_correct">make_predecessors_correct</a> [in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Constpropproof.html#make_shlimm_correct">make_shlimm_correct</a> [in <a href="backend.Constpropproof.html">backend.Constpropproof</a>]<br/>
-<a href="backend.Constpropproof.html#make_shrimm_correct">make_shrimm_correct</a> [in <a href="backend.Constpropproof.html">backend.Constpropproof</a>]<br/>
-<a href="backend.Constpropproof.html#make_shruimm_correct">make_shruimm_correct</a> [in <a href="backend.Constpropproof.html">backend.Constpropproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#make_stackaddr_correct">make_stackaddr_correct</a> [in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#make_store_correct">make_store_correct</a> [in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Constpropproof.html#make_xorimm_correct">make_xorimm_correct</a> [in <a href="backend.Constpropproof.html">backend.Constpropproof</a>]<br/>
-<a href="backend.RTLtyping.html#mapped_included_consistent">mapped_included_consistent</a> [in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.RTLtyping.html#mapped_list_included">mapped_list_included</a> [in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.Alloctyping_aux.html#map_f_getsrc_getdst">map_f_getsrc_getdst</a> [in <a href="backend.Alloctyping_aux.html">backend.Alloctyping_aux</a>]<br/>
-<a href="backend.Allocproof_aux.html#map_inv">map_inv</a> [in <a href="backend.Allocproof_aux.html">backend.Allocproof_aux</a>]<br/>
-<a href="backend.RTLgenproof1.html#map_wf_incr">map_wf_incr</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.Cminorgenproof.html#match_callstack_alloc_left">match_callstack_alloc_left</a> [in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#match_callstack_alloc_other">match_callstack_alloc_other</a> [in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#match_callstack_alloc_right">match_callstack_alloc_right</a> [in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#match_callstack_alloc_variables">match_callstack_alloc_variables</a> [in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#match_callstack_alloc_variables_rec">match_callstack_alloc_variables_rec</a> [in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#match_callstack_freelist">match_callstack_freelist</a> [in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#match_callstack_freelist_rec">match_callstack_freelist_rec</a> [in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#match_callstack_incr_bound">match_callstack_incr_bound</a> [in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#match_callstack_mapped">match_callstack_mapped</a> [in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#match_callstack_match_globalenvs">match_callstack_match_globalenvs</a> [in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#match_callstack_store_above">match_callstack_store_above</a> [in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#match_callstack_store_local">match_callstack_store_local</a> [in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#match_callstack_store_local_unchanged">match_callstack_store_local_unchanged</a> [in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#match_env_alloc_other">match_env_alloc_other</a> [in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#match_env_alloc_same">match_env_alloc_same</a> [in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.RTLgenproof1.html#match_env_empty">match_env_empty</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#match_env_exten">match_env_exten</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.Cminorgenproof.html#match_env_extensional">match_env_extensional</a> [in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.RTLgenproof1.html#match_env_find_reg">match_env_find_reg</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.Cminorgenproof.html#match_env_freelist">match_env_freelist</a> [in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.RTLgenproof1.html#match_env_invariant">match_env_invariant</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#match_env_letvar">match_env_letvar</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.Cminorgenproof.html#match_env_store_above">match_env_store_above</a> [in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#match_env_store_local">match_env_store_local</a> [in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#match_env_store_mapped">match_env_store_mapped</a> [in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.RTLgenproof1.html#match_env_update_temp">match_env_update_temp</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#match_env_update_var">match_env_update_var</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.Cminorgenproof.html#match_globalenvs_init">match_globalenvs_init</a> [in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.RTLgenproof1.html#match_init_env_init_reg">match_init_env_init_reg</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#match_set_locals">match_set_locals</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#match_set_params_init_regs">match_set_params_init_regs</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.Linearizetyping.html#max_over_instrs_bound">max_over_instrs_bound</a> [in <a href="backend.Linearizetyping.html">backend.Linearizetyping</a>]<br/>
-<a href="backend.Linearizetyping.html#max_over_list_bound">max_over_list_bound</a> [in <a href="backend.Linearizetyping.html">backend.Linearizetyping</a>]<br/>
-<a href="backend.Lineartyping.html#max_over_list_pos">max_over_list_pos</a> [in <a href="backend.Lineartyping.html">backend.Lineartyping</a>]<br/>
-<a href="backend.Linearizetyping.html#max_over_regs_of_funct_bound">max_over_regs_of_funct_bound</a> [in <a href="backend.Linearizetyping.html">backend.Linearizetyping</a>]<br/>
-<a href="backend.Lineartyping.html#max_over_regs_of_funct_pos">max_over_regs_of_funct_pos</a> [in <a href="backend.Lineartyping.html">backend.Lineartyping</a>]<br/>
-<a href="backend.Linearizetyping.html#max_over_slots_of_funct_bound">max_over_slots_of_funct_bound</a> [in <a href="backend.Linearizetyping.html">backend.Linearizetyping</a>]<br/>
-<a href="backend.Lineartyping.html#max_over_slots_of_funct_pos">max_over_slots_of_funct_pos</a> [in <a href="backend.Lineartyping.html">backend.Lineartyping</a>]<br/>
-<a href="backend.RTLtyping.html#member_correct">member_correct</a> [in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.Globalenvs.html#mem_add_globals_transf">mem_add_globals_transf</a> [in <a href="backend.Globalenvs.html">backend.Globalenvs</a>]<br/>
-<a href="lib.Sets.html#mem_add_other">mem_add_other</a> [in <a href="lib.Sets.html">lib.Sets</a>]<br/>
-<a href="lib.Sets.html#mem_add_same">mem_add_same</a> [in <a href="lib.Sets.html">lib.Sets</a>]<br/>
-<a href="backend.InterfGraph.html#mem_add_tail">mem_add_tail</a> [in <a href="backend.InterfGraph.html">backend.InterfGraph</a>]<br/>
-<a href="lib.Sets.html#mem_empty">mem_empty</a> [in <a href="lib.Sets.html">lib.Sets</a>]<br/>
-<a href="backend.Mem.html#mem_exten">mem_exten</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="lib.Sets.html#mem_remove_other">mem_remove_other</a> [in <a href="lib.Sets.html">lib.Sets</a>]<br/>
-<a href="lib.Sets.html#mem_remove_same">mem_remove_same</a> [in <a href="lib.Sets.html">lib.Sets</a>]<br/>
-<a href="lib.Sets.html#mem_union">mem_union</a> [in <a href="lib.Sets.html">lib.Sets</a>]<br/>
-<a href="lib.Integers.html#mkint_eq">mkint_eq</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#mods_divs">mods_divs</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Values.html#mods_divs">mods_divs</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="lib.Integers.html#modulus_pos">modulus_pos</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#modu_and">modu_and</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#modu_divu">modu_divu</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Values.html#modu_divu">modu_divu</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="lib.Integers.html#modu_divu_Euclid">modu_divu_Euclid</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Values.html#modu_pow2">modu_pow2</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="lib.Integers.html#mod_in_range">mod_in_range</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#mone_max_unsigned">mone_max_unsigned</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Alloctyping_aux.html#move_types_res">move_types_res</a> [in <a href="backend.Alloctyping_aux.html">backend.Alloctyping_aux</a>]<br/>
-<a href="backend.Alloctyping_aux.html#move_types_stepf">move_types_stepf</a> [in <a href="backend.Alloctyping_aux.html">backend.Alloctyping_aux</a>]<br/>
-<a href="backend.Locations.html#mreg_eq">mreg_eq</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Linearizetyping.html#mreg_is_bounded">mreg_is_bounded</a> [in <a href="backend.Linearizetyping.html">backend.Linearizetyping</a>]<br/>
-<a href="backend.Kildall.html#multiple_predecessors">multiple_predecessors</a> [in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="lib.Integers.html#mul_add_distr_l">mul_add_distr_l</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Values.html#mul_add_distr_l">mul_add_distr_l</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="lib.Integers.html#mul_add_distr_r">mul_add_distr_r</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Values.html#mul_add_distr_r">mul_add_distr_r</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="lib.Integers.html#mul_assoc">mul_assoc</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Values.html#mul_assoc">mul_assoc</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Values.html#mul_commut">mul_commut</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="lib.Integers.html#mul_commut">mul_commut</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#mul_one">mul_one</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#mul_pow2">mul_pow2</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Values.html#mul_pow2">mul_pow2</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="lib.Integers.html#mul_zero">mul_zero</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.RTLgenproof1.html#mutated_reg_in_map">mutated_reg_in_map</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<br/><br/><a name="lemma_N"></a><h2>N </h2>
-<a href="backend.Values.html#negate_cmp">negate_cmp</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="lib.Integers.html#negate_cmp">negate_cmp</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Values.html#negate_cmpf_eq">negate_cmpf_eq</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="lib.Integers.html#negate_cmpu">negate_cmpu</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Values.html#negate_cmpu">negate_cmpu</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Values.html#negate_cmp_mismatch">negate_cmp_mismatch</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Values.html#neg_add_distr">neg_add_distr</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="lib.Integers.html#neg_add_distr">neg_add_distr</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#neg_repr">neg_repr</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#neg_zero">neg_zero</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Values.html#neg_zero">neg_zero</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Parallelmove.html#neq_is_neq">neq_is_neq</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.RTLgenproof1.html#new_reg_fresh">new_reg_fresh</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#new_reg_incr">new_reg_incr</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#new_reg_not_in_map">new_reg_not_in_map</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#new_reg_not_mutated">new_reg_not_mutated</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#new_reg_return_ok">new_reg_return_ok</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#new_reg_valid">new_reg_valid</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.PPCgenproof1.html#nextinstr_inv">nextinstr_inv</a> [in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.PPCgenproof1.html#nextinstr_set_preg">nextinstr_set_preg</a> [in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.Locations.html#non_overlap_diff">non_overlap_diff</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Parallelmove.html#noOverlapaux_insert">noOverlapaux_insert</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#noOverlapaux_swap2">noOverlapaux_swap2</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#noOverlap_auxpop">noOverlap_auxpop</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#noOverlap_auxPop">noOverlap_auxPop</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#noOverlap_aux_app">noOverlap_aux_app</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#noOverlap_Front0">noOverlap_Front0</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#noOverlap_head">noOverlap_head</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#noOverlap_insert">noOverlap_insert</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#noOverlap_movBack">noOverlap_movBack</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#noOverlap_movBack0">noOverlap_movBack0</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#noOverlap_movFront">noOverlap_movFront</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#noOverlap_nil">noOverlap_nil</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#noOverlap_Pop">noOverlap_Pop</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#noOverlap_pop">noOverlap_pop</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#noOverlap_right">noOverlap_right</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#noOverlap_swap">noOverlap_swap</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#noO_diff">noO_diff</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Allocproof_aux.html#noO_list_pnilnil">noO_list_pnilnil</a> [in <a href="backend.Allocproof_aux.html">backend.Allocproof_aux</a>]<br/>
-<a href="backend.Parallelmove.html#noRead_app">noRead_app</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#noRead_by_path">noRead_by_path</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Allocproof_aux.html#norepet_SD">norepet_SD</a> [in <a href="backend.Allocproof_aux.html">backend.Allocproof_aux</a>]<br/>
-<a href="backend.Values.html#notbool_idem2">notbool_idem2</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Values.html#notbool_idem3">notbool_idem3</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="lib.Integers.html#notbool_isfalse_istrue">notbool_isfalse_istrue</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#notbool_istrue_isfalse">notbool_istrue_isfalse</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Values.html#notbool_is_bool">notbool_is_bool</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Values.html#notbool_negb_1">notbool_negb_1</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Values.html#notbool_negb_2">notbool_negb_2</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Values.html#notbool_xor">notbool_xor</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Parallelmove.html#notindst_nW">notindst_nW</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Locations.html#notin_disjoint">notin_disjoint</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#notin_not_in">notin_not_in</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Parallelmove.html#noTmpLast_lastnoTmp">noTmpLast_lastnoTmp</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#noTmpLast_Pop">noTmpLast_Pop</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#noTmpLast_pop">noTmpLast_pop</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#noTmpLast_popBack">noTmpLast_popBack</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#noTmpLast_push">noTmpLast_push</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#noTmpLast_tmpLast">noTmpLast_tmpLast</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#noTmpL_diff">noTmpL_diff</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#noTmp_app">noTmp_app</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#noTmp_append">noTmp_append</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#noTmP_noOverlap_aux">noTmP_noOverlap_aux</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#noTmp_noReadTmp">noTmp_noReadTmp</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#noTmp_noTmpLast">noTmp_noTmpLast</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#noTmp_pop">noTmp_pop</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#noWrite_in">noWrite_in</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#noWrite_insert">noWrite_insert</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#noWrite_movFront">noWrite_movFront</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#noWrite_pop">noWrite_pop</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#noWrite_swap">noWrite_swap</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#noWrite_tmpLast">noWrite_tmpLast</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Allocproof_aux.html#no_overlapD_inv">no_overlapD_inv</a> [in <a href="backend.Allocproof_aux.html">backend.Allocproof_aux</a>]<br/>
-<a href="backend.Allocproof_aux.html#no_overlapD_invf">no_overlapD_invf</a> [in <a href="backend.Allocproof_aux.html">backend.Allocproof_aux</a>]<br/>
-<a href="backend.Allocproof_aux.html#no_overlapD_invpp">no_overlapD_invpp</a> [in <a href="backend.Allocproof_aux.html">backend.Allocproof_aux</a>]<br/>
-<a href="backend.Allocproof_aux.html#no_overlapD_res">no_overlapD_res</a> [in <a href="backend.Allocproof_aux.html">backend.Allocproof_aux</a>]<br/>
-<a href="backend.Conventions.html#no_overlap_arguments">no_overlap_arguments</a> [in <a href="backend.Conventions.html">backend.Conventions</a>]<br/>
-<a href="backend.Allocproof_aux.html#no_overlap_list_pop">no_overlap_list_pop</a> [in <a href="backend.Allocproof_aux.html">backend.Allocproof_aux</a>]<br/>
-<a href="backend.Parallelmove.html#no_overlap_noOverlap">no_overlap_noOverlap</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Conventions.html#no_overlap_parameters">no_overlap_parameters</a> [in <a href="backend.Conventions.html">backend.Conventions</a>]<br/>
-<a href="backend.Allocproof_aux.html#no_overlap_temp">no_overlap_temp</a> [in <a href="backend.Allocproof_aux.html">backend.Allocproof_aux</a>]<br/>
-<a href="backend.Kildall.html#no_self_loop">no_self_loop</a> [in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="lib.Coqlib.html#nth_error_in">nth_error_in</a> [in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#nth_error_nil">nth_error_nil</a> [in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="backend.CSEproof.html#numbering_holds_exten">numbering_holds_exten</a> [in <a href="backend.CSEproof.html">backend.CSEproof</a>]<br/>
-<br/><br/><a name="lemma_O"></a><h2>O </h2>
-<a href="backend.Stackingproof.html#offset_of_index_disj">offset_of_index_disj</a> [in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="backend.Stackingproof.html#offset_of_index_no_overflow">offset_of_index_no_overflow</a> [in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="backend.Stackingproof.html#offset_of_index_valid">offset_of_index_valid</a> [in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="backend.Values.html#of_bool_is_bool">of_bool_is_bool</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="lib.Integers.html#one_bits_decomp">one_bits_decomp</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#one_bits_range">one_bits_range</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#one_not_zero">one_not_zero</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.union_find.html#option_sum">option_sum</a> [in <a href="lib.union_find.html">lib.union_find</a>]<br/>
-<a href="backend.Constpropproof.html#op_strength_reduction_correct">op_strength_reduction_correct</a> [in <a href="backend.Constpropproof.html">backend.Constpropproof</a>]<br/>
-<a href="backend.InterfGraph.html#ordered_pair_charact">ordered_pair_charact</a> [in <a href="backend.InterfGraph.html">backend.InterfGraph</a>]<br/>
-<a href="backend.InterfGraph.html#ordered_pair_sym">ordered_pair_sym</a> [in <a href="backend.InterfGraph.html">backend.InterfGraph</a>]<br/>
-<a href="backend.PPCgenproof1.html#orimm_correct">orimm_correct</a> [in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="lib.Integers.html#or_assoc">or_assoc</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Values.html#or_assoc">or_assoc</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="lib.Integers.html#or_commut">or_commut</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Values.html#or_commut">or_commut</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="lib.Integers.html#or_idem">or_idem</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#or_mone">or_mone</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Values.html#or_of_bool">or_of_bool</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="lib.Integers.html#or_rolm">or_rolm</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Values.html#or_rolm">or_rolm</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="lib.Integers.html#or_zero">or_zero</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Linearizetyping.html#outgoing_slot_bound">outgoing_slot_bound</a> [in <a href="backend.Linearizetyping.html">backend.Linearizetyping</a>]<br/>
-<a href="backend.Locations.html#overlap_aux_false_1">overlap_aux_false_1</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#overlap_aux_true_1">overlap_aux_true_1</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#overlap_aux_true_2">overlap_aux_true_2</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#overlap_not_diff">overlap_not_diff</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<br/><br/><a name="lemma_P"></a><h2>P </h2>
-<a href="backend.Allocproof.html#parallel_move_correct">parallel_move_correct</a> [in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.Allocproof_aux.html#parallel_move_correctX">parallel_move_correctX</a> [in <a href="backend.Allocproof_aux.html">backend.Allocproof_aux</a>]<br/>
-<a href="backend.Allocproof_aux.html#parallel_move_correct'">parallel_move_correct'</a> [in <a href="backend.Allocproof_aux.html">backend.Allocproof_aux</a>]<br/>
-<a href="backend.Parallelmove.html#path_pop">path_pop</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#path_tmpLast">path_tmpLast</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="lib.Coqlib.html#peq_false">peq_false</a> [in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#peq_true">peq_true</a> [in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="backend.Parallelmove.html#pexec_add">pexec_add</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#pexec_correct">pexec_correct</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#pexec_mov">pexec_mov</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#pexec_movBack">pexec_movBack</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#pexec_movFront">pexec_movFront</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#pexec_nop">pexec_nop</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#pexec_push">pexec_push</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#pexec_swap">pexec_swap</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#pexec_update">pexec_update</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="lib.Coqlib.html#Ple_refl">Ple_refl</a> [in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#Ple_succ">Ple_succ</a> [in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#Ple_trans">Ple_trans</a> [in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#Plt_ne">Plt_ne</a> [in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#Plt_Ple">Plt_Ple</a> [in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#Plt_Ple_trans">Plt_Ple_trans</a> [in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#Plt_strict">Plt_strict</a> [in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#Plt_succ">Plt_succ</a> [in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#Plt_succ_inv">Plt_succ_inv</a> [in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#Plt_trans">Plt_trans</a> [in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#Plt_trans_succ">Plt_trans_succ</a> [in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#Plt_wf">Plt_wf</a> [in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="backend.Parallelmove.html#Pmov_equation">Pmov_equation</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="lib.Coqlib.html#positive_Peano_ind">positive_Peano_ind</a> [in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#positive_rec_base">positive_rec_base</a> [in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#positive_rec_succ">positive_rec_succ</a> [in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#Ppred_Plt">Ppred_Plt</a> [in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="backend.Kildall.html#predecessors_correct">predecessors_correct</a> [in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.PPC.html#preg_eq">preg_eq</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPCgenproof1.html#preg_of_injective">preg_of_injective</a> [in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.PPCgenproof1.html#preg_of_is_data_reg">preg_of_is_data_reg</a> [in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.PPCgenproof1.html#preg_of_not">preg_of_not</a> [in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.PPCgenproof1.html#preg_of_not_GPR1">preg_of_not_GPR1</a> [in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.PPCgenproof1.html#preg_val">preg_val</a> [in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.Tunnelingtyping.html#program_typing_preserved">program_typing_preserved</a> [in <a href="backend.Tunnelingtyping.html">backend.Tunnelingtyping</a>]<br/>
-<a href="backend.Linearizetyping.html#program_typing_preserved">program_typing_preserved</a> [in <a href="backend.Linearizetyping.html">backend.Linearizetyping</a>]<br/>
-<a href="backend.Alloctyping.html#program_typing_preserved">program_typing_preserved</a> [in <a href="backend.Alloctyping.html">backend.Alloctyping</a>]<br/>
-<a href="backend.Stackingtyping.html#program_typing_preserved">program_typing_preserved</a> [in <a href="backend.Stackingtyping.html">backend.Stackingtyping</a>]<br/>
-<a href="backend.Globalenvs.html#prog_funct_transf_OK">prog_funct_transf_OK</a> [in <a href="backend.Globalenvs.html">backend.Globalenvs</a>]<br/>
-<a href="backend.Kildall.html#propagate_successors_charact1">propagate_successors_charact1</a> [in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Kildall.html#propagate_successors_charact2">propagate_successors_charact2</a> [in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Kildall.html#propagate_successors_invariant">propagate_successors_invariant</a> [in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Kildall.html#propagate_successors_P">propagate_successors_P</a> [in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Kildall.html#propagate_succ_charact">propagate_succ_charact</a> [in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Kildall.html#propagate_succ_incr">propagate_succ_incr</a> [in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Kildall.html#propagate_succ_incr_worklist">propagate_succ_incr_worklist</a> [in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Kildall.html#propagate_succ_list_charact">propagate_succ_list_charact</a> [in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Kildall.html#propagate_succ_list_incr">propagate_succ_list_incr</a> [in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Kildall.html#propagate_succ_list_incr_worklist">propagate_succ_list_incr_worklist</a> [in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Kildall.html#propagate_succ_list_records_changes">propagate_succ_list_records_changes</a> [in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Kildall.html#propagate_succ_records_changes">propagate_succ_records_changes</a> [in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<br/><br/><a name="lemma_R"></a><h2>R </h2>
-<a href="backend.Linearizeproof.html#reachable_correct_1">reachable_correct_1</a> [in <a href="backend.Linearizeproof.html">backend.Linearizeproof</a>]<br/>
-<a href="backend.Linearizeproof.html#reachable_correct_2">reachable_correct_2</a> [in <a href="backend.Linearizeproof.html">backend.Linearizeproof</a>]<br/>
-<a href="backend.Linearizeproof.html#reachable_entrypoint">reachable_entrypoint</a> [in <a href="backend.Linearizeproof.html">backend.Linearizeproof</a>]<br/>
-<a href="backend.Linearizeproof.html#reachable_successors">reachable_successors</a> [in <a href="backend.Linearizeproof.html">backend.Linearizeproof</a>]<br/>
-<a href="backend.Parallelmove.html#rebuild_l">rebuild_l</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.CSE.html#refl_ge">refl_ge</a> [in <a href="backend.CSE.html">backend.CSE</a>]<br/>
-<a href="backend.Coloringproof.html#regalloc_acceptable">regalloc_acceptable</a> [in <a href="backend.Coloringproof.html">backend.Coloringproof</a>]<br/>
-<a href="backend.Coloringproof.html#regalloc_correct_1">regalloc_correct_1</a> [in <a href="backend.Coloringproof.html">backend.Coloringproof</a>]<br/>
-<a href="backend.Coloringproof.html#regalloc_correct_2">regalloc_correct_2</a> [in <a href="backend.Coloringproof.html">backend.Coloringproof</a>]<br/>
-<a href="backend.Coloringproof.html#regalloc_correct_3">regalloc_correct_3</a> [in <a href="backend.Coloringproof.html">backend.Coloringproof</a>]<br/>
-<a href="backend.Allocproof.html#regalloc_disj_temporaries">regalloc_disj_temporaries</a> [in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.Allocproof.html#regalloc_norepet_norepet">regalloc_norepet_norepet</a> [in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.Allocproof.html#regalloc_noteq_diff">regalloc_noteq_diff</a> [in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.Allocproof.html#regalloc_notin_notin">regalloc_notin_notin</a> [in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.Allocproof.html#regalloc_not_temporary">regalloc_not_temporary</a> [in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.Coloringproof.html#regalloc_ok">regalloc_ok</a> [in <a href="backend.Coloringproof.html">backend.Coloringproof</a>]<br/>
-<a href="backend.Coloringproof.html#regalloc_preserves_types">regalloc_preserves_types</a> [in <a href="backend.Coloringproof.html">backend.Coloringproof</a>]<br/>
-<a href="backend.Conventions.html#register_classification">register_classification</a> [in <a href="backend.Conventions.html">backend.Conventions</a>]<br/>
-<a href="backend.Coloringproof.html#regsalloc_acceptable">regsalloc_acceptable</a> [in <a href="backend.Coloringproof.html">backend.Coloringproof</a>]<br/>
-<a href="backend.Constpropproof.html#regs_match_approx_increasing">regs_match_approx_increasing</a> [in <a href="backend.Constpropproof.html">backend.Constpropproof</a>]<br/>
-<a href="backend.Constpropproof.html#regs_match_approx_update">regs_match_approx_update</a> [in <a href="backend.Constpropproof.html">backend.Constpropproof</a>]<br/>
-<a href="backend.Allocproof.html#reg_for_spec">reg_for_spec</a> [in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.RTLgenproof1.html#reg_fresh_decr">reg_fresh_decr</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#reg_in_map_valid">reg_in_map_valid</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#reg_valid_incr">reg_valid_incr</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.CSEproof.html#reg_valnum_correct">reg_valnum_correct</a> [in <a href="backend.CSEproof.html">backend.CSEproof</a>]<br/>
-<a href="lib.Inclusion.html#remove_all_leaves_sound">remove_all_leaves_sound</a> [in <a href="lib.Inclusion.html">lib.Inclusion</a>]<br/>
-<a href="backend.RTLtyping.html#repet_correct">repet_correct</a> [in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.Parallelmove.html#replace_last_id">replace_last_id</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="lib.union_find.html#repr_aux_canon">repr_aux_canon</a> [in <a href="lib.union_find.html">lib.union_find</a>]<br/>
-<a href="lib.union_find.html#repr_aux_none">repr_aux_none</a> [in <a href="lib.union_find.html">lib.union_find</a>]<br/>
-<a href="lib.union_find.html#repr_aux_some">repr_aux_some</a> [in <a href="lib.union_find.html">lib.union_find</a>]<br/>
-<a href="lib.union_find.html#repr_empty">repr_empty</a> [in <a href="lib.union_find.html">lib.union_find</a>]<br/>
-<a href="lib.union_find.html#repr_rec_ext">repr_rec_ext</a> [in <a href="lib.union_find.html">lib.union_find</a>]<br/>
-<a href="lib.union_find.html#repr_repr">repr_repr</a> [in <a href="lib.union_find.html">lib.union_find</a>]<br/>
-<a href="lib.Integers.html#repr_signed">repr_signed</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#repr_unsigned">repr_unsigned</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.RTLgenproof1.html#reserve_instr_incr">reserve_instr_incr</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgen.html#reserve_instr_wf">reserve_instr_wf</a> [in <a href="backend.RTLgen.html">backend.RTLgen</a>]<br/>
-<a href="backend.Stackingproof.html#restore_callee_save_correct">restore_callee_save_correct</a> [in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="backend.Stackingproof.html#restore_float_callee_save_correct">restore_float_callee_save_correct</a> [in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="backend.Stackingproof.html#restore_float_callee_save_correct_rec">restore_float_callee_save_correct_rec</a> [in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="backend.Stackingproof.html#restore_int_callee_save_correct">restore_int_callee_save_correct</a> [in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="backend.Stackingproof.html#restore_int_callee_save_correct_rec">restore_int_callee_save_correct_rec</a> [in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="backend.Allocproof.html#return_regs_not_destroyed">return_regs_not_destroyed</a> [in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.Allocproof.html#return_regs_result">return_regs_result</a> [in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.RTLgenproof1.html#return_reg_ok_incr">return_reg_ok_incr</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="lib.Maps.html#rleaf">rleaf</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Integers.html#rolm_rolm">rolm_rolm</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Values.html#rolm_rolm">rolm_rolm</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="lib.Integers.html#rolm_zero">rolm_zero</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Values.html#rolm_zero">rolm_zero</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="lib.Integers.html#rol_and">rol_and</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#rol_or">rol_or</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#rol_rol">rol_rol</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#rol_zero">rol_zero</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<br/><br/><a name="lemma_S"></a><h2>S </h2>
-<a href="lib.union_find.html#sameclass_empty">sameclass_empty</a> [in <a href="lib.union_find.html">lib.union_find</a>]<br/>
-<a href="lib.union_find.html#sameclass_identify_1">sameclass_identify_1</a> [in <a href="lib.union_find.html">lib.union_find</a>]<br/>
-<a href="lib.union_find.html#sameclass_identify_2">sameclass_identify_2</a> [in <a href="lib.union_find.html">lib.union_find</a>]<br/>
-<a href="lib.union_find.html#sameclass_refl">sameclass_refl</a> [in <a href="lib.union_find.html">lib.union_find</a>]<br/>
-<a href="lib.union_find.html#sameclass_repr">sameclass_repr</a> [in <a href="lib.union_find.html">lib.union_find</a>]<br/>
-<a href="lib.union_find.html#sameclass_sym">sameclass_sym</a> [in <a href="lib.union_find.html">lib.union_find</a>]<br/>
-<a href="lib.union_find.html#sameclass_trans">sameclass_trans</a> [in <a href="lib.union_find.html">lib.union_find</a>]<br/>
-<a href="backend.Parallelmove.html#sameExec_reflexive">sameExec_reflexive</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#sameExec_transitive">sameExec_transitive</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Locations.html#same_not_diff">same_not_diff</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Coloringproof.html#same_typ_correct">same_typ_correct</a> [in <a href="backend.Coloringproof.html">backend.Coloringproof</a>]<br/>
-<a href="backend.Stackingproof.html#save_callee_save_correct">save_callee_save_correct</a> [in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="backend.Stackingproof.html#save_float_callee_save_correct">save_float_callee_save_correct</a> [in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="backend.Stackingproof.html#save_float_callee_save_correct_rec">save_float_callee_save_correct_rec</a> [in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="backend.Stackingproof.html#save_int_callee_save_correct">save_int_callee_save_correct</a> [in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="backend.Stackingproof.html#save_int_callee_save_correct_rec">save_int_callee_save_correct_rec</a> [in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="backend.Parallelmove.html#SB_Pmov">SB_Pmov</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Allocproof_aux.html#SDone_Pmov">SDone_Pmov</a> [in <a href="backend.Allocproof_aux.html">backend.Allocproof_aux</a>]<br/>
-<a href="backend.Allocproof_aux.html#SDone_stepf">SDone_stepf</a> [in <a href="backend.Allocproof_aux.html">backend.Allocproof_aux</a>]<br/>
-<a href="backend.Parallelmove.html#sD_nW">sD_nW</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#sD_pexec">sD_pexec</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Mem.html#setN_agree">setN_agree</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#setN_inject">setN_inject</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#setN_outside_agree">setN_outside_agree</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#setN_outside_inject">setN_outside_inject</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#set_cont_agree">set_cont_agree</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#set_cont_inject">set_cont_inject</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#set_cont_inside">set_cont_inside</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#set_cont_outside">set_cont_outside</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#set_cont_outside1">set_cont_outside1</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#set_cont_outside_agree">set_cont_outside_agree</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#set_cont_outside_inject">set_cont_outside_inject</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Cminorgenproof.html#set_locals_defined">set_locals_defined</a> [in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#set_locals_params_defined">set_locals_params_defined</a> [in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#set_params_defined">set_params_defined</a> [in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Stackingproof.html#set_slot_index">set_slot_index</a> [in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="backend.Machtyping.html#set_slot_link_invariant">set_slot_link_invariant</a> [in <a href="backend.Machtyping.html">backend.Machtyping</a>]<br/>
-<a href="backend.Stackingproof.html#set_slot_ok">set_slot_ok</a> [in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="backend.Stackingproof.html#shift_eval_addressing">shift_eval_addressing</a> [in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="backend.Stackingproof.html#shift_eval_operation">shift_eval_operation</a> [in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="backend.Values.html#shl_mul">shl_mul</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="lib.Integers.html#shl_mul">shl_mul</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#shl_mul_two_p">shl_mul_two_p</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#shl_rolm">shl_rolm</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Values.html#shl_rolm">shl_rolm</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="lib.Integers.html#shl_zero">shl_zero</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#shru_div_two_p">shru_div_two_p</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Values.html#shru_rolm">shru_rolm</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="lib.Integers.html#shru_rolm">shru_rolm</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#shru_zero">shru_zero</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Values.html#shrx_carry">shrx_carry</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="lib.Integers.html#shrx_carry">shrx_carry</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#shr_zero">shr_zero</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#signed_range">signed_range</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#signed_repr">signed_repr</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Allocproof.html#sig_function_translated">sig_function_translated</a> [in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#sig_transl_function">sig_transl_function</a> [in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Parallelmove.html#simpleDest_insert">simpleDest_insert</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#simpleDest_movBack">simpleDest_movBack</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#simpleDest_movFront">simpleDest_movFront</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#simpleDest_Pop">simpleDest_Pop</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#simpleDest_pop">simpleDest_pop</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#simpleDest_pop2">simpleDest_pop2</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#simpleDest_right">simpleDest_right</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#simpleDest_swap">simpleDest_swap</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#simpleDest_swap_app">simpleDest_swap_app</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#simpleDest_tmpLast">simpleDest_tmpLast</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Linearizetyping.html#size_arguments_bound">size_arguments_bound</a> [in <a href="backend.Linearizetyping.html">backend.Linearizetyping</a>]<br/>
-<a href="backend.Mem.html#size_chunk_pos">size_chunk_pos</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#size_mem_pos">size_mem_pos</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Stackingproof.html#size_no_overflow">size_no_overflow</a> [in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="backend.Stackingproof.html#size_pos">size_pos</a> [in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="backend.Locations.html#slot_eq">slot_eq</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Stackingproof.html#slot_gi">slot_gi</a> [in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="backend.Stackingproof.html#slot_gso">slot_gso</a> [in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="backend.Stackingproof.html#slot_gss">slot_gss</a> [in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="backend.Stackingproof.html#slot_iso">slot_iso</a> [in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="backend.Stackingproof.html#slot_iss">slot_iss</a> [in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="backend.Linearizetyping.html#slot_is_bounded">slot_is_bounded</a> [in <a href="backend.Linearizetyping.html">backend.Linearizetyping</a>]<br/>
-<a href="lib.Inclusion.html#sort_included">sort_included</a> [in <a href="lib.Inclusion.html">lib.Inclusion</a>]<br/>
-<a href="lib.Inclusion.html#sort_included2">sort_included2</a> [in <a href="lib.Inclusion.html">lib.Inclusion</a>]<br/>
-<a href="backend.Parallelmove.html#splitNone">splitNone</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#splitSome">splitSome</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#split_length">split_length</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Alloctyping_aux.html#split_move_incl">split_move_incl</a> [in <a href="backend.Alloctyping_aux.html">backend.Alloctyping_aux</a>]<br/>
-<a href="backend.PPCgenproof1.html#sp_val">sp_val</a> [in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.Alloctyping_aux.html#srcdst_tmp2_stepf">srcdst_tmp2_stepf</a> [in <a href="backend.Alloctyping_aux.html">backend.Alloctyping_aux</a>]<br/>
-<a href="backend.Alloctyping_aux.html#src_tmp2_res">src_tmp2_res</a> [in <a href="backend.Alloctyping_aux.html">backend.Alloctyping_aux</a>]<br/>
-<a href="backend.Linearizeproof.html#starts_with_correct">starts_with_correct</a> [in <a href="backend.Linearizeproof.html">backend.Linearizeproof</a>]<br/>
-<a href="backend.Kildall.html#start_state_good">start_state_good</a> [in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Kildall.html#start_state_in_entry">start_state_in_entry</a> [in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.RTLgenproof1.html#state_incr_extends">state_incr_extends</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#state_incr_refl">state_incr_refl</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#state_incr_trans">state_incr_trans</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#state_incr_trans2">state_incr_trans2</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#state_incr_trans3">state_incr_trans3</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#state_incr_trans4">state_incr_trans4</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#state_incr_trans5">state_incr_trans5</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#state_incr_trans6">state_incr_trans6</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.Parallelmove.html#stepf1_dec">stepf1_dec</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#stepf_dec">stepf_dec</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#stepf_dec0">stepf_dec0</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#stepf_dec0'">stepf_dec0'</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#stepf_pop">stepf_pop</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#stepf_popLoop">stepf_popLoop</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Allocproof_aux.html#stepInv_pnilnil">stepInv_pnilnil</a> [in <a href="backend.Allocproof_aux.html">backend.Allocproof_aux</a>]<br/>
-<a href="backend.Parallelmove.html#stepp_inv">stepp_inv</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#stepp_sameExec">stepp_sameExec</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#stepp_transitive">stepp_transitive</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.RTLtyping.html#step1">step1</a> [in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.RTLtyping.html#step2">step2</a> [in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.RTLtyping.html#step3">step3</a> [in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.RTLtyping.html#step4">step4</a> [in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.Parallelmove.html#step_dec">step_dec</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#step_dec0">step_dec0</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#step_inv">step_inv</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#step_inv_getdst">step_inv_getdst</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#step_inv_loop">step_inv_loop</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#step_inv_loop_aux">step_inv_loop_aux</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#step_inv_noOverlap">step_inv_noOverlap</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#step_inv_NoOverlap">step_inv_NoOverlap</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#step_inv_noTmp">step_inv_noTmp</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#step_inv_noTmpLast">step_inv_noTmpLast</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#step_inv_path">step_inv_path</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#step_inv_simpleDest">step_inv_simpleDest</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#step_sameExec">step_sameExec</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Kildall.html#step_state_good">step_state_good</a> [in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Parallelmove.html#step_stepp">step_stepp</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.RTLgenproof1.html#stmt_stmtlist_ind">stmt_stmtlist_ind</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.Parallelmove.html#STM_Pmov">STM_Pmov</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.PPCgenproof1.html#storeind_aux_correct">storeind_aux_correct</a> [in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.PPCgenproof1.html#storeind_correct">storeind_correct</a> [in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.Mem.html#storev_mapped_inject">storev_mapped_inject</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#storev_mapped_inject_1">storev_mapped_inject_1</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.PPCgenproof.html#storev_16_signed_unsigned">storev_16_signed_unsigned</a> [in <a href="backend.PPCgenproof.html">backend.PPCgenproof</a>]<br/>
-<a href="backend.PPCgenproof.html#storev_8_signed_unsigned">storev_8_signed_unsigned</a> [in <a href="backend.PPCgenproof.html">backend.PPCgenproof</a>]<br/>
-<a href="backend.Mem.html#store_agree">store_agree</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#store_alloc">store_alloc</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#store_contentmap_agree">store_contentmap_agree</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#store_contentmap_outside_agree">store_contentmap_outside_agree</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#store_contents_inject">store_contents_inject</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#store_contents_outside_inject">store_contents_outside_inject</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#store_inv">store_inv</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#store_in_bounds">store_in_bounds</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#store_is_in_bounds">store_is_in_bounds</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#store_mapped_inject">store_mapped_inject</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#store_mapped_inject_1">store_mapped_inject_1</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#store_outside_agree">store_outside_agree</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#store_outside_extends">store_outside_extends</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Cminorgenproof.html#store_parameters_correct">store_parameters_correct</a> [in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Mem.html#store_unmapped_inject">store_unmapped_inject</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#store_within_extends">store_within_extends</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Machtyping.html#subject_reduction">subject_reduction</a> [in <a href="backend.Machtyping.html">backend.Machtyping</a>]<br/>
-<a href="backend.RTLtyping.html#subject_reduction">subject_reduction</a> [in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.Machtyping.html#subject_reduction_function">subject_reduction_function</a> [in <a href="backend.Machtyping.html">backend.Machtyping</a>]<br/>
-<a href="backend.Machtyping.html#subject_reduction_instr">subject_reduction_instr</a> [in <a href="backend.Machtyping.html">backend.Machtyping</a>]<br/>
-<a href="backend.Machtyping.html#subject_reduction_instrs">subject_reduction_instrs</a> [in <a href="backend.Machtyping.html">backend.Machtyping</a>]<br/>
-<a href="backend.Values.html#sub_add_l">sub_add_l</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="lib.Integers.html#sub_add_l">sub_add_l</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#sub_add_opp">sub_add_opp</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Values.html#sub_add_opp">sub_add_opp</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Values.html#sub_add_r">sub_add_r</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="lib.Integers.html#sub_add_r">sub_add_r</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#sub_idem">sub_idem</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#sub_shifted">sub_shifted</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#sub_zero_l">sub_zero_l</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Values.html#sub_zero_r">sub_zero_r</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="lib.Integers.html#sub_zero_r">sub_zero_r</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.LTL.html#successors_aux_invariant">successors_aux_invariant</a> [in <a href="backend.LTL.html">backend.LTL</a>]<br/>
-<a href="backend.LTL.html#successors_correct">successors_correct</a> [in <a href="backend.LTL.html">backend.LTL</a>]<br/>
-<a href="backend.RTL.html#successors_correct">successors_correct</a> [in <a href="backend.RTL.html">backend.RTL</a>]<br/>
-<a href="lib.Integers.html#swap_cmp">swap_cmp</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Values.html#swap_cmp">swap_cmp</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Values.html#swap_cmpu">swap_cmpu</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="lib.Integers.html#swap_cmpu">swap_cmpu</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Values.html#swap_cmp_mismatch">swap_cmp_mismatch</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Globalenvs.html#symbols_add_globals_transf">symbols_add_globals_transf</a> [in <a href="backend.Globalenvs.html">backend.Globalenvs</a>]<br/>
-<a href="backend.Globalenvs.html#symbols_init_transf">symbols_init_transf</a> [in <a href="backend.Globalenvs.html">backend.Globalenvs</a>]<br/>
-<a href="backend.Tunnelingproof.html#symbols_preserved">symbols_preserved</a> [in <a href="backend.Tunnelingproof.html">backend.Tunnelingproof</a>]<br/>
-<a href="backend.Allocproof.html#symbols_preserved">symbols_preserved</a> [in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#symbols_preserved">symbols_preserved</a> [in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Constpropproof.html#symbols_preserved">symbols_preserved</a> [in <a href="backend.Constpropproof.html">backend.Constpropproof</a>]<br/>
-<a href="backend.PPCgenproof.html#symbols_preserved">symbols_preserved</a> [in <a href="backend.PPCgenproof.html">backend.PPCgenproof</a>]<br/>
-<a href="backend.RTLgenproof.html#symbols_preserved">symbols_preserved</a> [in <a href="backend.RTLgenproof.html">backend.RTLgenproof</a>]<br/>
-<a href="backend.Linearizeproof.html#symbols_preserved">symbols_preserved</a> [in <a href="backend.Linearizeproof.html">backend.Linearizeproof</a>]<br/>
-<a href="backend.CSEproof.html#symbols_preserved">symbols_preserved</a> [in <a href="backend.CSEproof.html">backend.CSEproof</a>]<br/>
-<a href="backend.Stackingproof.html#symbols_preserved">symbols_preserved</a> [in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<br/><br/><a name="lemma_T"></a><h2>T </h2>
-<a href="backend.RTLgenproof1.html#target_regs_not_mutated">target_regs_not_mutated</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#target_regs_ok_incr">target_regs_ok_incr</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#target_regs_valid">target_regs_valid</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#target_reg_not_mutated">target_reg_not_mutated</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#target_reg_ok_incr">target_reg_ok_incr</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#target_reg_valid">target_reg_valid</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.Conventions.html#temporaries_not_acceptable">temporaries_not_acceptable</a> [in <a href="backend.Conventions.html">backend.Conventions</a>]<br/>
-<a href="backend.RTLtyping.html#teq_correct">teq_correct</a> [in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="lib.Inclusion.html#test_inclusion_sound">test_inclusion_sound</a> [in <a href="lib.Inclusion.html">lib.Inclusion</a>]<br/>
-<a href="backend.CSE.html#top_ge">top_ge</a> [in <a href="backend.CSE.html">backend.CSE</a>]<br/>
-<a href="backend.Constpropproof.html#transfer_correct">transfer_correct</a> [in <a href="backend.Constpropproof.html">backend.Constpropproof</a>]<br/>
-<a href="backend.CSEproof.html#transfer_correct">transfer_correct</a> [in <a href="backend.CSEproof.html">backend.CSEproof</a>]<br/>
-<a href="backend.Main.html#transform_partial_program_compose">transform_partial_program_compose</a> [in <a href="backend.Main.html">backend.Main</a>]<br/>
-<a href="backend.AST.html#transform_partial_program_function">transform_partial_program_function</a> [in <a href="backend.AST.html">backend.AST</a>]<br/>
-<a href="backend.AST.html#transform_partial_program_main">transform_partial_program_main</a> [in <a href="backend.AST.html">backend.AST</a>]<br/>
-<a href="backend.AST.html#transform_program_function">transform_program_function</a> [in <a href="backend.AST.html">backend.AST</a>]<br/>
-<a href="backend.Main.html#transform_program_partial_total">transform_program_partial_total</a> [in <a href="backend.Main.html">backend.Main</a>]<br/>
-<a href="backend.Globalenvs.html#transform_program_transform_partial_program">transform_program_transform_partial_program</a> [in <a href="backend.Globalenvs.html">backend.Globalenvs</a>]<br/>
-<a href="backend.Main.html#transf_cminor_program2_correct">transf_cminor_program2_correct</a> [in <a href="backend.Main.html">backend.Main</a>]<br/>
-<a href="backend.Main.html#transf_cminor_program_correct">transf_cminor_program_correct</a> [in <a href="backend.Main.html">backend.Main</a>]<br/>
-<a href="backend.Main.html#transf_cminor_program_equiv">transf_cminor_program_equiv</a> [in <a href="backend.Main.html">backend.Main</a>]<br/>
-<a href="backend.CSE.html#transf_code_wf">transf_code_wf</a> [in <a href="backend.CSE.html">backend.CSE</a>]<br/>
-<a href="backend.Constprop.html#transf_code_wf">transf_code_wf</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.RTL.html#transf_code_wf">transf_code_wf</a> [in <a href="backend.RTL.html">backend.RTL</a>]<br/>
-<a href="backend.Main.html#transf_csharpminor_program2_correct">transf_csharpminor_program2_correct</a> [in <a href="backend.Main.html">backend.Main</a>]<br/>
-<a href="backend.Main.html#transf_csharpminor_program_correct">transf_csharpminor_program_correct</a> [in <a href="backend.Main.html">backend.Main</a>]<br/>
-<a href="backend.Main.html#transf_csharpminor_program_equiv">transf_csharpminor_program_equiv</a> [in <a href="backend.Main.html">backend.Main</a>]<br/>
-<a href="backend.Allocproof.html#transf_entrypoint_correct">transf_entrypoint_correct</a> [in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.Allocation.html#transf_entrypoint_wf">transf_entrypoint_wf</a> [in <a href="backend.Allocation.html">backend.Allocation</a>]<br/>
-<a href="backend.Linearizeproof.html#transf_function_correct">transf_function_correct</a> [in <a href="backend.Linearizeproof.html">backend.Linearizeproof</a>]<br/>
-<a href="backend.PPCgenproof.html#transf_function_correct">transf_function_correct</a> [in <a href="backend.PPCgenproof.html">backend.PPCgenproof</a>]<br/>
-<a href="backend.Stackingproof.html#transf_function_correct">transf_function_correct</a> [in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="backend.CSEproof.html#transf_function_correct">transf_function_correct</a> [in <a href="backend.CSEproof.html">backend.CSEproof</a>]<br/>
-<a href="backend.Constpropproof.html#transf_funct_correct">transf_funct_correct</a> [in <a href="backend.Constpropproof.html">backend.Constpropproof</a>]<br/>
-<a href="backend.Main.html#transf_partial_program_compose">transf_partial_program_compose</a> [in <a href="backend.Main.html">backend.Main</a>]<br/>
-<a href="backend.Linearizeproof.html#transf_program_correct">transf_program_correct</a> [in <a href="backend.Linearizeproof.html">backend.Linearizeproof</a>]<br/>
-<a href="backend.Tunnelingproof.html#transf_program_correct">transf_program_correct</a> [in <a href="backend.Tunnelingproof.html">backend.Tunnelingproof</a>]<br/>
-<a href="backend.Constpropproof.html#transf_program_correct">transf_program_correct</a> [in <a href="backend.Constpropproof.html">backend.Constpropproof</a>]<br/>
-<a href="backend.PPCgenproof.html#transf_program_correct">transf_program_correct</a> [in <a href="backend.PPCgenproof.html">backend.PPCgenproof</a>]<br/>
-<a href="backend.CSEproof.html#transf_program_correct">transf_program_correct</a> [in <a href="backend.CSEproof.html">backend.CSEproof</a>]<br/>
-<a href="backend.Main.html#transf_program_partial_total">transf_program_partial_total</a> [in <a href="backend.Main.html">backend.Main</a>]<br/>
-<a href="backend.Globalenvs.html#transf_program_transf_partial_program">transf_program_transf_partial_program</a> [in <a href="backend.Globalenvs.html">backend.Globalenvs</a>]<br/>
-<a href="lib.Integers.html#translate_cmp">translate_cmp</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#translate_eq">translate_eq</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#translate_lt">translate_lt</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.PPCgenproof.html#transl_code_label">transl_code_label</a> [in <a href="backend.PPCgenproof.html">backend.PPCgenproof</a>]<br/>
-<a href="backend.RTLgenproof.html#transl_condition_CEcondition_correct">transl_condition_CEcondition_correct</a> [in <a href="backend.RTLgenproof.html">backend.RTLgenproof</a>]<br/>
-<a href="backend.RTLgenproof.html#transl_condition_CEcond_correct">transl_condition_CEcond_correct</a> [in <a href="backend.RTLgenproof.html">backend.RTLgenproof</a>]<br/>
-<a href="backend.RTLgenproof.html#transl_condition_CEfalse_correct">transl_condition_CEfalse_correct</a> [in <a href="backend.RTLgenproof.html">backend.RTLgenproof</a>]<br/>
-<a href="backend.RTLgenproof.html#transl_condition_CEtrue_correct">transl_condition_CEtrue_correct</a> [in <a href="backend.RTLgenproof.html">backend.RTLgenproof</a>]<br/>
-<a href="backend.RTLgenproof1.html#transl_condition_incr">transl_condition_incr</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.PPCgenproof1.html#transl_cond_correct">transl_cond_correct</a> [in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.PPCgenproof1.html#transl_cond_correct_aux">transl_cond_correct_aux</a> [in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.Cminorgenproof.html#transl_exprlist_Econs_correct">transl_exprlist_Econs_correct</a> [in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.RTLgenproof.html#transl_exprlist_Econs_correct">transl_exprlist_Econs_correct</a> [in <a href="backend.RTLgenproof.html">backend.RTLgenproof</a>]<br/>
-<a href="backend.RTLgenproof.html#transl_exprlist_Enil_correct">transl_exprlist_Enil_correct</a> [in <a href="backend.RTLgenproof.html">backend.RTLgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#transl_exprlist_Enil_correct">transl_exprlist_Enil_correct</a> [in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.RTLgenproof1.html#transl_exprlist_incr">transl_exprlist_incr</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#transl_expr_condition_exprlist_incr">transl_expr_condition_exprlist_incr</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.Cminorgenproof.html#transl_expr_Eaddrof_global_correct">transl_expr_Eaddrof_global_correct</a> [in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#transl_expr_Eaddrof_local_correct">transl_expr_Eaddrof_local_correct</a> [in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#transl_expr_Eassign_correct">transl_expr_Eassign_correct</a> [in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.RTLgenproof.html#transl_expr_Eassign_correct">transl_expr_Eassign_correct</a> [in <a href="backend.RTLgenproof.html">backend.RTLgenproof</a>]<br/>
-<a href="backend.RTLgenproof.html#transl_expr_Ecall_correct">transl_expr_Ecall_correct</a> [in <a href="backend.RTLgenproof.html">backend.RTLgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#transl_expr_Ecall_correct">transl_expr_Ecall_correct</a> [in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.RTLgenproof.html#transl_expr_Econdition_correct">transl_expr_Econdition_correct</a> [in <a href="backend.RTLgenproof.html">backend.RTLgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#transl_expr_Econdition_false_correct">transl_expr_Econdition_false_correct</a> [in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#transl_expr_Econdition_true_correct">transl_expr_Econdition_true_correct</a> [in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.RTLgenproof.html#transl_expr_Eletvar_correct">transl_expr_Eletvar_correct</a> [in <a href="backend.RTLgenproof.html">backend.RTLgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#transl_expr_Eletvar_correct">transl_expr_Eletvar_correct</a> [in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#transl_expr_Elet_correct">transl_expr_Elet_correct</a> [in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.RTLgenproof.html#transl_expr_Elet_correct">transl_expr_Elet_correct</a> [in <a href="backend.RTLgenproof.html">backend.RTLgenproof</a>]<br/>
-<a href="backend.RTLgenproof.html#transl_expr_Eload_correct">transl_expr_Eload_correct</a> [in <a href="backend.RTLgenproof.html">backend.RTLgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#transl_expr_Eload_correct">transl_expr_Eload_correct</a> [in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.RTLgenproof.html#transl_expr_Eop_correct">transl_expr_Eop_correct</a> [in <a href="backend.RTLgenproof.html">backend.RTLgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#transl_expr_Eop_correct">transl_expr_Eop_correct</a> [in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.RTLgenproof.html#transl_expr_Estore_correct">transl_expr_Estore_correct</a> [in <a href="backend.RTLgenproof.html">backend.RTLgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#transl_expr_Estore_correct">transl_expr_Estore_correct</a> [in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#transl_expr_Evar_correct">transl_expr_Evar_correct</a> [in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.RTLgenproof.html#transl_expr_Evar_correct">transl_expr_Evar_correct</a> [in <a href="backend.RTLgenproof.html">backend.RTLgenproof</a>]<br/>
-<a href="backend.RTLgenproof1.html#transl_expr_incr">transl_expr_incr</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.PPCgenproof.html#transl_find_label">transl_find_label</a> [in <a href="backend.PPCgenproof.html">backend.PPCgenproof</a>]<br/>
-<a href="backend.Stackingproof.html#transl_find_label">transl_find_label</a> [in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#transl_funcall_correct">transl_funcall_correct</a> [in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.RTLgenproof.html#transl_funcall_correct">transl_funcall_correct</a> [in <a href="backend.RTLgenproof.html">backend.RTLgenproof</a>]<br/>
-<a href="backend.Allocproof.html#transl_function_correct">transl_function_correct</a> [in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#transl_function_correct">transl_function_correct</a> [in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Allocproof.html#transl_function_correctness">transl_function_correctness</a> [in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.RTLgenproof.html#transl_function_correctness">transl_function_correctness</a> [in <a href="backend.RTLgenproof.html">backend.RTLgenproof</a>]<br/>
-<a href="backend.Allocproof.html#transl_Icall_correct">transl_Icall_correct</a> [in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.Allocproof.html#transl_Icond_false_correct">transl_Icond_false_correct</a> [in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.Allocproof.html#transl_Icond_true_correct">transl_Icond_true_correct</a> [in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.Allocproof.html#transl_Iload_correct">transl_Iload_correct</a> [in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.Allocproof.html#transl_Inop_correct">transl_Inop_correct</a> [in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.PPCgenproof.html#transl_instr_label">transl_instr_label</a> [in <a href="backend.PPCgenproof.html">backend.PPCgenproof</a>]<br/>
-<a href="backend.Allocproof.html#transl_Iop_correct">transl_Iop_correct</a> [in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.Allocproof.html#transl_Istore_correct">transl_Istore_correct</a> [in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.PPCgenproof1.html#transl_load_correct">transl_load_correct</a> [in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.PPCgenproof1.html#transl_load_store_correct">transl_load_store_correct</a> [in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.Allocproof.html#transl_one_correct">transl_one_correct</a> [in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.PPCgenproof1.html#transl_op_correct">transl_op_correct</a> [in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.RTLgenproof.html#transl_program_correct">transl_program_correct</a> [in <a href="backend.RTLgenproof.html">backend.RTLgenproof</a>]<br/>
-<a href="backend.Stackingproof.html#transl_program_correct">transl_program_correct</a> [in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="backend.Allocproof.html#transl_program_correct">transl_program_correct</a> [in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#transl_program_correct">transl_program_correct</a> [in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Allocproof.html#transl_refl_correct">transl_refl_correct</a> [in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.RTLgenproof1.html#transl_stmtlist_incr">transl_stmtlist_incr</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof.html#transl_stmtlist_Scons_continue_correct">transl_stmtlist_Scons_continue_correct</a> [in <a href="backend.RTLgenproof.html">backend.RTLgenproof</a>]<br/>
-<a href="backend.RTLgenproof.html#transl_stmtlist_Scons_stop_correct">transl_stmtlist_Scons_stop_correct</a> [in <a href="backend.RTLgenproof.html">backend.RTLgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#transl_stmtlist_Scons_1_correct">transl_stmtlist_Scons_1_correct</a> [in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#transl_stmtlist_Scons_2_correct">transl_stmtlist_Scons_2_correct</a> [in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.RTLgenproof.html#transl_stmtlist_Snil_correct">transl_stmtlist_Snil_correct</a> [in <a href="backend.RTLgenproof.html">backend.RTLgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#transl_stmtlist_Snil_correct">transl_stmtlist_Snil_correct</a> [in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.RTLgenproof1.html#transl_stmt_incr">transl_stmt_incr</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof.html#transl_stmt_Sblock_correct">transl_stmt_Sblock_correct</a> [in <a href="backend.RTLgenproof.html">backend.RTLgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#transl_stmt_Sblock_correct">transl_stmt_Sblock_correct</a> [in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.RTLgenproof.html#transl_stmt_Sexit_correct">transl_stmt_Sexit_correct</a> [in <a href="backend.RTLgenproof.html">backend.RTLgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#transl_stmt_Sexit_correct">transl_stmt_Sexit_correct</a> [in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.RTLgenproof.html#transl_stmt_Sexpr_correct">transl_stmt_Sexpr_correct</a> [in <a href="backend.RTLgenproof.html">backend.RTLgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#transl_stmt_Sexpr_correct">transl_stmt_Sexpr_correct</a> [in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.RTLgenproof.html#transl_stmt_Sifthenelse_correct">transl_stmt_Sifthenelse_correct</a> [in <a href="backend.RTLgenproof.html">backend.RTLgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#transl_stmt_Sifthenelse_false_correct">transl_stmt_Sifthenelse_false_correct</a> [in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#transl_stmt_Sifthenelse_true_correct">transl_stmt_Sifthenelse_true_correct</a> [in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#transl_stmt_Sloop_exit_correct">transl_stmt_Sloop_exit_correct</a> [in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#transl_stmt_Sloop_loop_correct">transl_stmt_Sloop_loop_correct</a> [in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.RTLgenproof.html#transl_stmt_Sloop_loop_correct">transl_stmt_Sloop_loop_correct</a> [in <a href="backend.RTLgenproof.html">backend.RTLgenproof</a>]<br/>
-<a href="backend.RTLgenproof.html#transl_stmt_Sloop_stop_correct">transl_stmt_Sloop_stop_correct</a> [in <a href="backend.RTLgenproof.html">backend.RTLgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#transl_stmt_Sreturn_none_correct">transl_stmt_Sreturn_none_correct</a> [in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.RTLgenproof.html#transl_stmt_Sreturn_none_correct">transl_stmt_Sreturn_none_correct</a> [in <a href="backend.RTLgenproof.html">backend.RTLgenproof</a>]<br/>
-<a href="backend.RTLgenproof.html#transl_stmt_Sreturn_some_correct">transl_stmt_Sreturn_some_correct</a> [in <a href="backend.RTLgenproof.html">backend.RTLgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#transl_stmt_Sreturn_some_correct">transl_stmt_Sreturn_some_correct</a> [in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.RTLgenproof1.html#transl_stmt_stmtlist_incr">transl_stmt_stmtlist_incr</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.PPCgenproof1.html#transl_store_correct">transl_store_correct</a> [in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.Allocproof.html#transl_trans_correct">transl_trans_correct</a> [in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.Tunnelingproof.html#tunnel_function_correct">tunnel_function_correct</a> [in <a href="backend.Tunnelingproof.html">backend.Tunnelingproof</a>]<br/>
-<a href="lib.Coqlib.html#two_power_nat_O">two_power_nat_O</a> [in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#two_power_nat_pos">two_power_nat_pos</a> [in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="backend.Locations.html#typesize_pos">typesize_pos</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.RTLtyping.html#type_args_complete">type_args_complete</a> [in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.RTLtyping.html#type_args_correct">type_args_correct</a> [in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.RTLtyping.html#type_args_extends">type_args_extends</a> [in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.RTLtyping.html#type_args_included">type_args_included</a> [in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.RTLtyping.html#type_args_mapped">type_args_mapped</a> [in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.RTLtyping.html#type_args_res_complete">type_args_res_complete</a> [in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.RTLtyping.html#type_args_res_included">type_args_res_included</a> [in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.RTLtyping.html#type_args_res_ros_included">type_args_res_ros_included</a> [in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.RTLtyping.html#type_arg_complete">type_arg_complete</a> [in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.RTLtyping.html#type_arg_correct">type_arg_correct</a> [in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.RTLtyping.html#type_arg_correct_1">type_arg_correct_1</a> [in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.RTLtyping.html#type_arg_extends">type_arg_extends</a> [in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.RTLtyping.html#type_arg_included">type_arg_included</a> [in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.RTLtyping.html#type_arg_mapped">type_arg_mapped</a> [in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.RTLtyping.html#type_instrs_extends">type_instrs_extends</a> [in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.RTLtyping.html#type_instrs_included">type_instrs_included</a> [in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.RTLtyping.html#type_instr_included">type_instr_included</a> [in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.Op.html#type_of_chunk_correct">type_of_chunk_correct</a> [in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Op.html#type_of_operation_sound">type_of_operation_sound</a> [in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.RTLtyping.html#type_res_complete">type_res_complete</a> [in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.RTLtyping.html#type_res_correct">type_res_correct</a> [in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.RTLtyping.html#type_ros_complete">type_ros_complete</a> [in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.RTLtyping.html#type_ros_correct">type_ros_correct</a> [in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.RTLtyping.html#type_rtl_function_correct">type_rtl_function_correct</a> [in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.RTLtyping.html#type_rtl_function_instrs">type_rtl_function_instrs</a> [in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.RTLtyping.html#type_rtl_function_norepet">type_rtl_function_norepet</a> [in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.RTLtyping.html#type_rtl_function_params">type_rtl_function_params</a> [in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.Alloctyping_aux.html#T_type">T_type</a> [in <a href="backend.Alloctyping_aux.html">backend.Alloctyping_aux</a>]<br/>
-<br/><br/><a name="lemma_U"></a><h2>U </h2>
-<a href="backend.Values.html#undef_is_bool">undef_is_bool</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Stackingproof.html#unfold_transf_function">unfold_transf_function</a> [in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="backend.Linearizeproof.html#unique_labels_lin_block">unique_labels_lin_block</a> [in <a href="backend.Linearizeproof.html">backend.Linearizeproof</a>]<br/>
-<a href="backend.Linearizeproof.html#unique_labels_lin_function">unique_labels_lin_function</a> [in <a href="backend.Linearizeproof.html">backend.Linearizeproof</a>]<br/>
-<a href="backend.Linearizeproof.html#unique_labels_lin_rec">unique_labels_lin_rec</a> [in <a href="backend.Linearizeproof.html">backend.Linearizeproof</a>]<br/>
-<a href="lib.Coqlib.html#unroll_positive_rec">unroll_positive_rec</a> [in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Integers.html#unsigned_range">unsigned_range</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#unsigned_range_2">unsigned_range_2</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#unsigned_repr">unsigned_repr</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Parallelmove.html#unsplit_move">unsplit_move</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.RTLgenproof1.html#update_instr_extends">update_instr_extends</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#update_instr_incr">update_instr_incr</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgen.html#update_instr_wf">update_instr_wf</a> [in <a href="backend.RTLgen.html">backend.RTLgen</a>]<br/>
-<a href="backend.Mem.html#update_o">update_o</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#update_s">update_s</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<br/><br/><a name="lemma_V"></a><h2>V </h2>
-<a href="backend.Mem.html#valid_block_alloc">valid_block_alloc</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#valid_block_free">valid_block_free</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#valid_block_store">valid_block_store</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.RTLgenproof1.html#valid_fresh_absurd">valid_fresh_absurd</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#valid_fresh_different">valid_fresh_different</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.Mem.html#valid_new_block">valid_new_block</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#valid_not_valid_diff">valid_not_valid_diff</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#valid_pointer_inject_no_overflow">valid_pointer_inject_no_overflow</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.CSEproof.html#valnum_regs_holds">valnum_regs_holds</a> [in <a href="backend.CSEproof.html">backend.CSEproof</a>]<br/>
-<a href="backend.CSEproof.html#valnum_reg_holds">valnum_reg_holds</a> [in <a href="backend.CSEproof.html">backend.CSEproof</a>]<br/>
-<a href="backend.CSEproof.html#valu_agree_list">valu_agree_list</a> [in <a href="backend.CSEproof.html">backend.CSEproof</a>]<br/>
-<a href="backend.CSEproof.html#valu_agree_refl">valu_agree_refl</a> [in <a href="backend.CSEproof.html">backend.CSEproof</a>]<br/>
-<a href="backend.CSEproof.html#valu_agree_trans">valu_agree_trans</a> [in <a href="backend.CSEproof.html">backend.CSEproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#val_content_inject_cast">val_content_inject_cast</a> [in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Mem.html#val_content_inject_incr">val_content_inject_incr</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#val_inject_incr">val_inject_incr</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#val_list_inject_incr">val_list_inject_incr</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Constpropproof.html#val_match_approx_increasing">val_match_approx_increasing</a> [in <a href="backend.Constpropproof.html">backend.Constpropproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#vars_vals_match_extensional">vars_vals_match_extensional</a> [in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#vars_vals_match_holds">vars_vals_match_holds</a> [in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#vars_vals_match_holds_1">vars_vals_match_holds_1</a> [in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#var_addr_global_correct">var_addr_global_correct</a> [in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#var_addr_local_correct">var_addr_local_correct</a> [in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#var_get_correct">var_get_correct</a> [in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#var_set_correct">var_set_correct</a> [in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<br/><br/><a name="lemma_W"></a><h2>W </h2>
-<a href="backend.CSEproof.html#wf_add_load">wf_add_load</a> [in <a href="backend.CSEproof.html">backend.CSEproof</a>]<br/>
-<a href="backend.CSEproof.html#wf_add_op">wf_add_op</a> [in <a href="backend.CSEproof.html">backend.CSEproof</a>]<br/>
-<a href="backend.CSEproof.html#wf_add_rhs">wf_add_rhs</a> [in <a href="backend.CSEproof.html">backend.CSEproof</a>]<br/>
-<a href="backend.CSEproof.html#wf_analyze">wf_analyze</a> [in <a href="backend.CSEproof.html">backend.CSEproof</a>]<br/>
-<a href="lib.union_find.html#wf_empty">wf_empty</a> [in <a href="lib.union_find.html">lib.union_find</a>]<br/>
-<a href="backend.CSEproof.html#wf_empty_numbering">wf_empty_numbering</a> [in <a href="backend.CSEproof.html">backend.CSEproof</a>]<br/>
-<a href="backend.CSEproof.html#wf_equation_increasing">wf_equation_increasing</a> [in <a href="backend.CSEproof.html">backend.CSEproof</a>]<br/>
-<a href="backend.CSEproof.html#wf_kill_loads">wf_kill_loads</a> [in <a href="backend.CSEproof.html">backend.CSEproof</a>]<br/>
-<a href="backend.CSEproof.html#wf_rhs_increasing">wf_rhs_increasing</a> [in <a href="backend.CSEproof.html">backend.CSEproof</a>]<br/>
-<a href="backend.CSEproof.html#wf_transfer">wf_transfer</a> [in <a href="backend.CSEproof.html">backend.CSEproof</a>]<br/>
-<a href="backend.Tunneling.html#wf_tunneled_code">wf_tunneled_code</a> [in <a href="backend.Tunneling.html">backend.Tunneling</a>]<br/>
-<a href="backend.CSEproof.html#wf_valnum_reg">wf_valnum_reg</a> [in <a href="backend.CSEproof.html">backend.CSEproof</a>]<br/>
-<a href="backend.CSEproof.html#wf_valnum_regs">wf_valnum_regs</a> [in <a href="backend.CSEproof.html">backend.CSEproof</a>]<br/>
-<a href="backend.Alloctyping.html#wt_add_call">wt_add_call</a> [in <a href="backend.Alloctyping.html">backend.Alloctyping</a>]<br/>
-<a href="backend.Alloctyping.html#wt_add_cond">wt_add_cond</a> [in <a href="backend.Alloctyping.html">backend.Alloctyping</a>]<br/>
-<a href="backend.Alloctyping.html#wt_add_entry">wt_add_entry</a> [in <a href="backend.Alloctyping.html">backend.Alloctyping</a>]<br/>
-<a href="backend.Alloctyping.html#wt_add_load">wt_add_load</a> [in <a href="backend.Alloctyping.html">backend.Alloctyping</a>]<br/>
-<a href="backend.Alloctyping.html#wt_add_move">wt_add_move</a> [in <a href="backend.Alloctyping.html">backend.Alloctyping</a>]<br/>
-<a href="backend.Alloctyping_aux.html#wt_add_moves">wt_add_moves</a> [in <a href="backend.Alloctyping_aux.html">backend.Alloctyping_aux</a>]<br/>
-<a href="backend.Alloctyping.html#wt_add_op_move">wt_add_op_move</a> [in <a href="backend.Alloctyping.html">backend.Alloctyping</a>]<br/>
-<a href="backend.Alloctyping.html#wt_add_op_others">wt_add_op_others</a> [in <a href="backend.Alloctyping.html">backend.Alloctyping</a>]<br/>
-<a href="backend.Alloctyping.html#wt_add_op_undef">wt_add_op_undef</a> [in <a href="backend.Alloctyping.html">backend.Alloctyping</a>]<br/>
-<a href="backend.Alloctyping.html#wt_add_reload">wt_add_reload</a> [in <a href="backend.Alloctyping.html">backend.Alloctyping</a>]<br/>
-<a href="backend.Alloctyping.html#wt_add_reloads">wt_add_reloads</a> [in <a href="backend.Alloctyping.html">backend.Alloctyping</a>]<br/>
-<a href="backend.Alloctyping.html#wt_add_return">wt_add_return</a> [in <a href="backend.Alloctyping.html">backend.Alloctyping</a>]<br/>
-<a href="backend.Alloctyping.html#wt_add_spill">wt_add_spill</a> [in <a href="backend.Alloctyping.html">backend.Alloctyping</a>]<br/>
-<a href="backend.Alloctyping.html#wt_add_store">wt_add_store</a> [in <a href="backend.Alloctyping.html">backend.Alloctyping</a>]<br/>
-<a href="backend.Alloctyping.html#wt_add_undefs">wt_add_undefs</a> [in <a href="backend.Alloctyping.html">backend.Alloctyping</a>]<br/>
-<a href="backend.Stackingtyping.html#wt_fold_right">wt_fold_right</a> [in <a href="backend.Stackingtyping.html">backend.Stackingtyping</a>]<br/>
-<a href="backend.Machtyping.html#wt_get_slot">wt_get_slot</a> [in <a href="backend.Machtyping.html">backend.Machtyping</a>]<br/>
-<a href="backend.Machtyping.html#wt_init_frame">wt_init_frame</a> [in <a href="backend.Machtyping.html">backend.Machtyping</a>]<br/>
-<a href="backend.RTLtyping.html#wt_init_regs">wt_init_regs</a> [in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.Stackingtyping.html#wt_instrs_cons">wt_instrs_cons</a> [in <a href="backend.Stackingtyping.html">backend.Stackingtyping</a>]<br/>
-<a href="backend.Linearizetyping.html#wt_linearize_block">wt_linearize_block</a> [in <a href="backend.Linearizetyping.html">backend.Linearizetyping</a>]<br/>
-<a href="backend.Linearizetyping.html#wt_linearize_body">wt_linearize_body</a> [in <a href="backend.Linearizetyping.html">backend.Linearizetyping</a>]<br/>
-<a href="backend.Stackingtyping.html#wt_Msetstack'">wt_Msetstack'</a> [in <a href="backend.Stackingtyping.html">backend.Stackingtyping</a>]<br/>
-<a href="backend.Alloctyping.html#wt_parallel_move">wt_parallel_move</a> [in <a href="backend.Alloctyping.html">backend.Alloctyping</a>]<br/>
-<a href="backend.Alloctyping_aux.html#wt_parallel_moveX">wt_parallel_moveX</a> [in <a href="backend.Alloctyping_aux.html">backend.Alloctyping_aux</a>]<br/>
-<a href="backend.Alloctyping_aux.html#wt_parallel_move'">wt_parallel_move'</a> [in <a href="backend.Alloctyping_aux.html">backend.Alloctyping_aux</a>]<br/>
-<a href="backend.RTLtyping.html#wt_regset_assign">wt_regset_assign</a> [in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.RTLtyping.html#wt_regset_list">wt_regset_list</a> [in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.Alloctyping.html#wt_regs_for">wt_regs_for</a> [in <a href="backend.Alloctyping.html">backend.Alloctyping</a>]<br/>
-<a href="backend.Alloctyping.html#wt_regs_for_rec">wt_regs_for_rec</a> [in <a href="backend.Alloctyping.html">backend.Alloctyping</a>]<br/>
-<a href="backend.Alloctyping.html#wt_reg_for">wt_reg_for</a> [in <a href="backend.Alloctyping.html">backend.Alloctyping</a>]<br/>
-<a href="backend.Stackingtyping.html#wt_restore_callee_save">wt_restore_callee_save</a> [in <a href="backend.Stackingtyping.html">backend.Stackingtyping</a>]<br/>
-<a href="backend.Stackingtyping.html#wt_restore_float_callee_save">wt_restore_float_callee_save</a> [in <a href="backend.Stackingtyping.html">backend.Stackingtyping</a>]<br/>
-<a href="backend.Stackingtyping.html#wt_restore_int_callee_save">wt_restore_int_callee_save</a> [in <a href="backend.Stackingtyping.html">backend.Stackingtyping</a>]<br/>
-<a href="backend.Alloctyping.html#wt_rtl_function">wt_rtl_function</a> [in <a href="backend.Alloctyping.html">backend.Alloctyping</a>]<br/>
-<a href="backend.Stackingtyping.html#wt_save_callee_save">wt_save_callee_save</a> [in <a href="backend.Stackingtyping.html">backend.Stackingtyping</a>]<br/>
-<a href="backend.Stackingtyping.html#wt_save_float_callee_save">wt_save_float_callee_save</a> [in <a href="backend.Stackingtyping.html">backend.Stackingtyping</a>]<br/>
-<a href="backend.Stackingtyping.html#wt_save_int_callee_save">wt_save_int_callee_save</a> [in <a href="backend.Stackingtyping.html">backend.Stackingtyping</a>]<br/>
-<a href="backend.Machtyping.html#wt_setreg">wt_setreg</a> [in <a href="backend.Machtyping.html">backend.Machtyping</a>]<br/>
-<a href="backend.Machtyping.html#wt_set_slot">wt_set_slot</a> [in <a href="backend.Machtyping.html">backend.Machtyping</a>]<br/>
-<a href="backend.Alloctyping.html#wt_transf_entrypoint">wt_transf_entrypoint</a> [in <a href="backend.Alloctyping.html">backend.Alloctyping</a>]<br/>
-<a href="backend.Stackingtyping.html#wt_transf_function">wt_transf_function</a> [in <a href="backend.Stackingtyping.html">backend.Stackingtyping</a>]<br/>
-<a href="backend.Alloctyping.html#wt_transf_function">wt_transf_function</a> [in <a href="backend.Alloctyping.html">backend.Alloctyping</a>]<br/>
-<a href="backend.Linearizetyping.html#wt_transf_function">wt_transf_function</a> [in <a href="backend.Linearizetyping.html">backend.Linearizetyping</a>]<br/>
-<a href="backend.Alloctyping.html#wt_transf_instr">wt_transf_instr</a> [in <a href="backend.Alloctyping.html">backend.Alloctyping</a>]<br/>
-<a href="backend.Alloctyping.html#wt_transf_instrs">wt_transf_instrs</a> [in <a href="backend.Alloctyping.html">backend.Alloctyping</a>]<br/>
-<a href="backend.Stackingtyping.html#wt_transl_instr">wt_transl_instr</a> [in <a href="backend.Stackingtyping.html">backend.Stackingtyping</a>]<br/>
-<a href="backend.Tunnelingtyping.html#wt_tunnel_block">wt_tunnel_block</a> [in <a href="backend.Tunnelingtyping.html">backend.Tunnelingtyping</a>]<br/>
-<a href="backend.Tunnelingtyping.html#wt_tunnel_function">wt_tunnel_function</a> [in <a href="backend.Tunnelingtyping.html">backend.Tunnelingtyping</a>]<br/>
-<br/><br/><a name="lemma_X"></a><h2>X </h2>
-<a href="lib.Maps.html#xcombine_lr">xcombine_lr</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#xelements_complete">xelements_complete</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#xelements_correct">xelements_correct</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#xelements_hi">xelements_hi</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#xelements_ho">xelements_ho</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#xelements_ih">xelements_ih</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#xelements_ii">xelements_ii</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#xelements_io">xelements_io</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#xelements_keys_norepet">xelements_keys_norepet</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#xelements_oh">xelements_oh</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#xelements_oi">xelements_oi</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#xelements_oo">xelements_oo</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#xgcombine">xgcombine</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#xgcombine_l">xgcombine_l</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#xgcombine_r">xgcombine_r</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#xget_left">xget_left</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#xgmap">xgmap</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="backend.PPCgenproof1.html#xorimm_correct">xorimm_correct</a> [in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="lib.Integers.html#xor_assoc">xor_assoc</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Values.html#xor_assoc">xor_assoc</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Values.html#xor_commut">xor_commut</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="lib.Integers.html#xor_commut">xor_commut</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#xor_one_one">xor_one_one</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#xor_zero">xor_zero</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#xor_zero_one">xor_zero_one</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<br/><br/><a name="lemma_Z"></a><h2>Z </h2>
-<a href="lib.Coqlib.html#Zdiv_small">Zdiv_small</a> [in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#Zdiv_unique">Zdiv_unique</a> [in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#zeq_false">zeq_false</a> [in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#zeq_true">zeq_true</a> [in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#zle_false">zle_false</a> [in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#zle_true">zle_true</a> [in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#zlt_false">zlt_false</a> [in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#zlt_true">zlt_true</a> [in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#Zmax_bound_l">Zmax_bound_l</a> [in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#Zmax_bound_r">Zmax_bound_r</a> [in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#Zmax_spec">Zmax_spec</a> [in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#Zmin_spec">Zmin_spec</a> [in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#Zmod_small">Zmod_small</a> [in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#Zmod_unique">Zmod_unique</a> [in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Integers.html#Z_bin_decomp_range">Z_bin_decomp_range</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#Z_bin_decomp_shift_add">Z_bin_decomp_shift_add</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#Z_of_bits_excl">Z_of_bits_excl</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#Z_of_bits_exten">Z_of_bits_exten</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#Z_of_bits_of_Z">Z_of_bits_of_Z</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#Z_of_bits_range">Z_of_bits_range</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#Z_of_bits_range_2">Z_of_bits_range_2</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#Z_of_bits_shift">Z_of_bits_shift</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#Z_of_bits_shifts">Z_of_bits_shifts</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#Z_of_bits_shifts_rev">Z_of_bits_shifts_rev</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#Z_of_bits_shift_rev">Z_of_bits_shift_rev</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#Z_one_bits_powerserie">Z_one_bits_powerserie</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#Z_one_bits_range">Z_one_bits_range</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#Z_shift_add_bin_decomp">Z_shift_add_bin_decomp</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#Z_shift_add_inj">Z_shift_add_inj</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<br/><br/><hr/>
-<h1>Constructor Index</h1>
-<a name="constructor_A"></a><h2>A </h2>
-<a href="backend.Op.html#Abased">Abased</a> [in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Cmconstr.html#addf_case1">addf_case1</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#addf_case2">addf_case2</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#addf_default">addf_default</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#addimm_case1">addimm_case1</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#addimm_case2">addimm_case2</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#addimm_case3">addimm_case3</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#addimm_case4">addimm_case4</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#addimm_default">addimm_default</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#addressing_case1">addressing_case1</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#addressing_case2">addressing_case2</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#addressing_case3">addressing_case3</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#addressing_case4">addressing_case4</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#addressing_case5">addressing_case5</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#addressing_default">addressing_default</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Constprop.html#addr_strength_reduction_case1">addr_strength_reduction_case1</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#addr_strength_reduction_case2">addr_strength_reduction_case2</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#addr_strength_reduction_case3">addr_strength_reduction_case3</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#addr_strength_reduction_default">addr_strength_reduction_default</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Cmconstr.html#add_case1">add_case1</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#add_case2">add_case2</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#add_case3">add_case3</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#add_case4">add_case4</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#add_case5">add_case5</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#add_default">add_default</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Op.html#Aglobal">Aglobal</a> [in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Op.html#Aindexed">Aindexed</a> [in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Op.html#Aindexed2">Aindexed2</a> [in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Op.html#Ainstack">Ainstack</a> [in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Csharpminor.html#alloc_variables_cons">alloc_variables_cons</a> [in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Csharpminor.html#alloc_variables_nil">alloc_variables_nil</a> [in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<br/><br/><a name="constructor_B"></a><h2>B </h2>
-<a href="backend.LTL.html#Bcall">Bcall</a> [in <a href="backend.LTL.html">backend.LTL</a>]<br/>
-<a href="backend.LTL.html#Bcond">Bcond</a> [in <a href="backend.LTL.html">backend.LTL</a>]<br/>
-<a href="backend.LTL.html#Bgetstack">Bgetstack</a> [in <a href="backend.LTL.html">backend.LTL</a>]<br/>
-<a href="backend.LTL.html#Bgoto">Bgoto</a> [in <a href="backend.LTL.html">backend.LTL</a>]<br/>
-<a href="backend.Csharpminor.html#bind_parameters_cons">bind_parameters_cons</a> [in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Csharpminor.html#bind_parameters_nil">bind_parameters_nil</a> [in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.LTL.html#Bload">Bload</a> [in <a href="backend.LTL.html">backend.LTL</a>]<br/>
-<a href="backend.Values.html#bool_of_val_int_true">bool_of_val_int_true</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.LTL.html#Bop">Bop</a> [in <a href="backend.LTL.html">backend.LTL</a>]<br/>
-<a href="lib.Lattice.html#Bot">Bot</a> [in <a href="lib.Lattice.html">lib.Lattice</a>]<br/>
-<a href="lib.Lattice.html#Bot_except">Bot_except</a> [in <a href="lib.Lattice.html">lib.Lattice</a>]<br/>
-<a href="backend.LTL.html#Breturn">Breturn</a> [in <a href="backend.LTL.html">backend.LTL</a>]<br/>
-<a href="backend.LTL.html#Bsetstack">Bsetstack</a> [in <a href="backend.LTL.html">backend.LTL</a>]<br/>
-<a href="backend.LTL.html#Bstore">Bstore</a> [in <a href="backend.LTL.html">backend.LTL</a>]<br/>
-<br/><br/><a name="constructor_C"></a><h2>C </h2>
-<a href="backend.Machabstr2mach.html#callstack_dom_cons">callstack_dom_cons</a> [in <a href="backend.Machabstr2mach.html">backend.Machabstr2mach</a>]<br/>
-<a href="backend.Machabstr2mach.html#callstack_dom_nil">callstack_dom_nil</a> [in <a href="backend.Machabstr2mach.html">backend.Machabstr2mach</a>]<br/>
-<a href="backend.Machabstr2mach.html#callstack_linked_cons">callstack_linked_cons</a> [in <a href="backend.Machabstr2mach.html">backend.Machabstr2mach</a>]<br/>
-<a href="backend.Machabstr2mach.html#callstack_linked_nil">callstack_linked_nil</a> [in <a href="backend.Machabstr2mach.html">backend.Machabstr2mach</a>]<br/>
-<a href="backend.Machabstr2mach.html#callstack_linked_one">callstack_linked_one</a> [in <a href="backend.Machabstr2mach.html">backend.Machabstr2mach</a>]<br/>
-<a href="backend.PPC.html#CARRY">CARRY</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.Op.html#Ccomp">Ccomp</a> [in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Op.html#Ccompf">Ccompf</a> [in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Op.html#Ccompimm">Ccompimm</a> [in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Op.html#Ccompu">Ccompu</a> [in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Op.html#Ccompuimm">Ccompuimm</a> [in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Cminor.html#CEcond">CEcond</a> [in <a href="backend.Cminor.html">backend.Cminor</a>]<br/>
-<a href="backend.Cminor.html#CEcondition">CEcondition</a> [in <a href="backend.Cminor.html">backend.Cminor</a>]<br/>
-<a href="backend.Cminor.html#CEfalse">CEfalse</a> [in <a href="backend.Cminor.html">backend.Cminor</a>]<br/>
-<a href="backend.AST.html#Ceq">Ceq</a> [in <a href="backend.AST.html">backend.AST</a>]<br/>
-<a href="backend.Cminor.html#CEtrue">CEtrue</a> [in <a href="backend.Cminor.html">backend.Cminor</a>]<br/>
-<a href="backend.AST.html#Cge">Cge</a> [in <a href="backend.AST.html">backend.AST</a>]<br/>
-<a href="backend.AST.html#Cgt">Cgt</a> [in <a href="backend.AST.html">backend.AST</a>]<br/>
-<a href="backend.PPC.html#Cint">Cint</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.AST.html#Cle">Cle</a> [in <a href="backend.AST.html">backend.AST</a>]<br/>
-<a href="backend.AST.html#Clt">Clt</a> [in <a href="backend.AST.html">backend.AST</a>]<br/>
-<a href="backend.Op.html#Cmasknotzero">Cmasknotzero</a> [in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Op.html#Cmaskzero">Cmaskzero</a> [in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.AST.html#Cne">Cne</a> [in <a href="backend.AST.html">backend.AST</a>]<br/>
-<a href="backend.Op.html#Cnotcompf">Cnotcompf</a> [in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.LTL.html#Cont">Cont</a> [in <a href="backend.LTL.html">backend.LTL</a>]<br/>
-<a href="backend.Mem.html#Cont">Cont</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#content_inject_cont">content_inject_cont</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#content_inject_datum16">content_inject_datum16</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#content_inject_datum32">content_inject_datum32</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#content_inject_datum64">content_inject_datum64</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#content_inject_datum8">content_inject_datum8</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#content_inject_undef">content_inject_undef</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.PPC.html#CRbit_0">CRbit_0</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#CRbit_1">CRbit_1</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#CRbit_2">CRbit_2</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#CRbit_3">CRbit_3</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#CR0_0">CR0_0</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#CR0_1">CR0_1</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#CR0_2">CR0_2</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#CR0_3">CR0_3</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.Constprop.html#csr_case1">csr_case1</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#csr_case2">csr_case2</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#csr_default">csr_default</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.PPC.html#Csymbol_high_signed">Csymbol_high_signed</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Csymbol_high_unsigned">Csymbol_high_unsigned</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Csymbol_low_signed">Csymbol_low_signed</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Csymbol_low_unsigned">Csymbol_low_unsigned</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#CTR">CTR</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<br/><br/><a name="constructor_D"></a><h2>D </h2>
-<a href="backend.Mem.html#Datum16">Datum16</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#Datum32">Datum32</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#Datum64">Datum64</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#Datum8">Datum8</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Cmconstr.html#divu_case1">divu_case1</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#divu_default">divu_default</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Parallelmove.html#dstepp_refl">dstepp_refl</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#dstepp_trans">dstepp_trans</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#dstep_nop">dstep_nop</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#dstep_pop">dstep_pop</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#dstep_pop_loop">dstep_pop_loop</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#dstep_push">dstep_push</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#dstep_start">dstep_start</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<br/><br/><a name="constructor_E"></a><h2>E </h2>
-<a href="backend.Csharpminor.html#Eaddrof">Eaddrof</a> [in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Cminor.html#Eassign">Eassign</a> [in <a href="backend.Cminor.html">backend.Cminor</a>]<br/>
-<a href="backend.Csharpminor.html#Eassign">Eassign</a> [in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Csharpminor.html#Ecall">Ecall</a> [in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Cminor.html#Ecall">Ecall</a> [in <a href="backend.Cminor.html">backend.Cminor</a>]<br/>
-<a href="backend.Csharpminor.html#Econdition">Econdition</a> [in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Cminor.html#Econdition">Econdition</a> [in <a href="backend.Cminor.html">backend.Cminor</a>]<br/>
-<a href="backend.Cminor.html#Econs">Econs</a> [in <a href="backend.Cminor.html">backend.Cminor</a>]<br/>
-<a href="backend.Csharpminor.html#Econs">Econs</a> [in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Csharpminor.html#Elet">Elet</a> [in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Cminor.html#Elet">Elet</a> [in <a href="backend.Cminor.html">backend.Cminor</a>]<br/>
-<a href="backend.Cminor.html#Eletvar">Eletvar</a> [in <a href="backend.Cminor.html">backend.Cminor</a>]<br/>
-<a href="backend.Csharpminor.html#Eletvar">Eletvar</a> [in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Cminor.html#Eload">Eload</a> [in <a href="backend.Cminor.html">backend.Cminor</a>]<br/>
-<a href="backend.Csharpminor.html#Eload">Eload</a> [in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Csharpminor.html#Enil">Enil</a> [in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Cminor.html#Enil">Enil</a> [in <a href="backend.Cminor.html">backend.Cminor</a>]<br/>
-<a href="backend.Csharpminor.html#Eop">Eop</a> [in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Cminor.html#Eop">Eop</a> [in <a href="backend.Cminor.html">backend.Cminor</a>]<br/>
-<a href="backend.RTLgen.html#Error">Error</a> [in <a href="backend.RTLgen.html">backend.RTLgen</a>]<br/>
-<a href="backend.PPC.html#Error">Error</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.Cminor.html#Estore">Estore</a> [in <a href="backend.Cminor.html">backend.Cminor</a>]<br/>
-<a href="backend.Csharpminor.html#Estore">Estore</a> [in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Csharpminor.html#eval_Evar">eval_Evar</a> [in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Cminor.html#eval_Evar">eval_Evar</a> [in <a href="backend.Cminor.html">backend.Cminor</a>]<br/>
-<a href="backend.Constprop.html#eval_static_condition_case1">eval_static_condition_case1</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_condition_case2">eval_static_condition_case2</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_condition_case3">eval_static_condition_case3</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_condition_case4">eval_static_condition_case4</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_condition_case5">eval_static_condition_case5</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_condition_case6">eval_static_condition_case6</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_condition_case7">eval_static_condition_case7</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_condition_case8">eval_static_condition_case8</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_condition_default">eval_static_condition_default</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_operation_case1">eval_static_operation_case1</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_operation_case11">eval_static_operation_case11</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_operation_case12">eval_static_operation_case12</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_operation_case13">eval_static_operation_case13</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_operation_case14">eval_static_operation_case14</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_operation_case15">eval_static_operation_case15</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_operation_case16">eval_static_operation_case16</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_operation_case17">eval_static_operation_case17</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_operation_case18">eval_static_operation_case18</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_operation_case19">eval_static_operation_case19</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_operation_case2">eval_static_operation_case2</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_operation_case20">eval_static_operation_case20</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_operation_case21">eval_static_operation_case21</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_operation_case22">eval_static_operation_case22</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_operation_case23">eval_static_operation_case23</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_operation_case24">eval_static_operation_case24</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_operation_case25">eval_static_operation_case25</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_operation_case26">eval_static_operation_case26</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_operation_case27">eval_static_operation_case27</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_operation_case28">eval_static_operation_case28</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_operation_case29">eval_static_operation_case29</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_operation_case3">eval_static_operation_case3</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_operation_case30">eval_static_operation_case30</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_operation_case31">eval_static_operation_case31</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_operation_case32">eval_static_operation_case32</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_operation_case33">eval_static_operation_case33</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_operation_case34">eval_static_operation_case34</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_operation_case35">eval_static_operation_case35</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_operation_case36">eval_static_operation_case36</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_operation_case37">eval_static_operation_case37</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_operation_case38">eval_static_operation_case38</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_operation_case39">eval_static_operation_case39</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_operation_case4">eval_static_operation_case4</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_operation_case40">eval_static_operation_case40</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_operation_case41">eval_static_operation_case41</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_operation_case42">eval_static_operation_case42</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_operation_case43">eval_static_operation_case43</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_operation_case44">eval_static_operation_case44</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_operation_case45">eval_static_operation_case45</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_operation_case46">eval_static_operation_case46</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_operation_case47">eval_static_operation_case47</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_operation_case6">eval_static_operation_case6</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_operation_case7">eval_static_operation_case7</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_operation_case8">eval_static_operation_case8</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_operation_case9">eval_static_operation_case9</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_operation_default">eval_static_operation_default</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Cminor.html#Evar">Evar</a> [in <a href="backend.Cminor.html">backend.Cminor</a>]<br/>
-<a href="backend.Csharpminor.html#Evar">Evar</a> [in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.LTL.html#exec_Bgetstack">exec_Bgetstack</a> [in <a href="backend.LTL.html">backend.LTL</a>]<br/>
-<a href="backend.RTL.html#exec_Iload">exec_Iload</a> [in <a href="backend.RTL.html">backend.RTL</a>]<br/>
-<a href="backend.RTL.html#exec_Inop">exec_Inop</a> [in <a href="backend.RTL.html">backend.RTL</a>]<br/>
-<a href="backend.RTL.html#exec_Iop">exec_Iop</a> [in <a href="backend.RTL.html">backend.RTL</a>]<br/>
-<a href="backend.Linear.html#exec_Lgetstack">exec_Lgetstack</a> [in <a href="backend.Linear.html">backend.Linear</a>]<br/>
-<a href="backend.Mach.html#exec_Mgetparam">exec_Mgetparam</a> [in <a href="backend.Mach.html">backend.Mach</a>]<br/>
-<a href="backend.Mach.html#exec_Mgetstack">exec_Mgetstack</a> [in <a href="backend.Mach.html">backend.Mach</a>]<br/>
-<a href="backend.Machabstr.html#exec_Mgetstack">exec_Mgetstack</a> [in <a href="backend.Machabstr.html">backend.Machabstr</a>]<br/>
-<a href="backend.Mach.html#exec_Mlabel">exec_Mlabel</a> [in <a href="backend.Mach.html">backend.Mach</a>]<br/>
-<a href="backend.Machabstr.html#exec_Mlabel">exec_Mlabel</a> [in <a href="backend.Machabstr.html">backend.Machabstr</a>]<br/>
-<a href="backend.Mach.html#exec_Msetstack">exec_Msetstack</a> [in <a href="backend.Mach.html">backend.Mach</a>]<br/>
-<a href="backend.PPC.html#exec_one">exec_one</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#exec_refl">exec_refl</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#exec_step_intro">exec_step_intro</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPCgenproof1.html#exec_straight_refl">exec_straight_refl</a> [in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.PPCgenproof1.html#exec_straight_step">exec_straight_step</a> [in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.PPC.html#exec_trans">exec_trans</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<br/><br/><a name="constructor_F"></a><h2>F </h2>
-<a href="backend.Stacking.html#FI_arg">FI_arg</a> [in <a href="backend.Stacking.html">backend.Stacking</a>]<br/>
-<a href="backend.Stacking.html#FI_local">FI_local</a> [in <a href="backend.Stacking.html">backend.Stacking</a>]<br/>
-<a href="backend.Stacking.html#FI_saved_float">FI_saved_float</a> [in <a href="backend.Stacking.html">backend.Stacking</a>]<br/>
-<a href="backend.Stacking.html#FI_saved_int">FI_saved_int</a> [in <a href="backend.Stacking.html">backend.Stacking</a>]<br/>
-<a href="backend.PPC.html#FPR0">FPR0</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#FPR1">FPR1</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#FPR10">FPR10</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#FPR11">FPR11</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#FPR12">FPR12</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#FPR13">FPR13</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#FPR14">FPR14</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#FPR15">FPR15</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#FPR16">FPR16</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#FPR17">FPR17</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#FPR18">FPR18</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#FPR19">FPR19</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#FPR2">FPR2</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#FPR20">FPR20</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#FPR21">FPR21</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#FPR22">FPR22</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#FPR23">FPR23</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#FPR24">FPR24</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#FPR25">FPR25</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#FPR26">FPR26</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#FPR27">FPR27</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#FPR28">FPR28</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#FPR29">FPR29</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#FPR3">FPR3</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#FPR30">FPR30</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#FPR31">FPR31</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#FPR4">FPR4</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#FPR5">FPR5</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#FPR6">FPR6</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#FPR7">FPR7</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#FPR8">FPR8</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#FPR9">FPR9</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#FR">FR</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.Machabstr2mach.html#frame_match_intro">frame_match_intro</a> [in <a href="backend.Machabstr2mach.html">backend.Machabstr2mach</a>]<br/>
-<a href="backend.Locations.html#FT1">FT1</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#FT2">FT2</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#FT3">FT3</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#F1">F1</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#F10">F10</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#F14">F14</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#F15">F15</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#F16">F16</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#F17">F17</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#F18">F18</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#F19">F19</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#F2">F2</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#F20">F20</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#F21">F21</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#F22">F22</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#F23">F23</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#F24">F24</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#F25">F25</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#F26">F26</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#F27">F27</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#F28">F28</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#F29">F29</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#F3">F3</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#F30">F30</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#F31">F31</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#F4">F4</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#F5">F5</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#F6">F6</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#F7">F7</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#F8">F8</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#F9">F9</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<br/><br/><a name="constructor_G"></a><h2>G </h2>
-<a href="backend.Machabstr.html#get_slot_intro">get_slot_intro</a> [in <a href="backend.Machabstr.html">backend.Machabstr</a>]<br/>
-<a href="backend.PPC.html#GPR0">GPR0</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#GPR1">GPR1</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#GPR10">GPR10</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#GPR11">GPR11</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#GPR12">GPR12</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#GPR13">GPR13</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#GPR14">GPR14</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#GPR15">GPR15</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#GPR16">GPR16</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#GPR17">GPR17</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#GPR18">GPR18</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#GPR19">GPR19</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#GPR2">GPR2</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#GPR20">GPR20</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#GPR21">GPR21</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#GPR22">GPR22</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#GPR23">GPR23</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#GPR24">GPR24</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#GPR25">GPR25</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#GPR26">GPR26</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#GPR27">GPR27</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#GPR28">GPR28</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#GPR29">GPR29</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#GPR3">GPR3</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#GPR30">GPR30</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#GPR31">GPR31</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#GPR4">GPR4</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#GPR5">GPR5</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#GPR6">GPR6</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#GPR7">GPR7</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#GPR8">GPR8</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#GPR9">GPR9</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<br/><br/><a name="constructor_I"></a><h2>I </h2>
-<a href="backend.Locations.html#Incoming">Incoming</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="lib.Lattice.html#Inj">Inj</a> [in <a href="lib.Lattice.html">lib.Lattice</a>]<br/>
-<a href="backend.RTL.html#Inop">Inop</a> [in <a href="backend.RTL.html">backend.RTL</a>]<br/>
-<a href="backend.Cmconstrproof.html#insert_lenv_S">insert_lenv_S</a> [in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Cmconstrproof.html#insert_lenv_0">insert_lenv_0</a> [in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.PPC.html#IR">IR</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.Linearizeproof.html#is_tail_cons">is_tail_cons</a> [in <a href="backend.Linearizeproof.html">backend.Linearizeproof</a>]<br/>
-<a href="backend.Linearizeproof.html#is_tail_refl">is_tail_refl</a> [in <a href="backend.Linearizeproof.html">backend.Linearizeproof</a>]<br/>
-<a href="backend.Locations.html#IT1">IT1</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#IT2">IT2</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#IT3">IT3</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<br/><br/><a name="constructor_L"></a><h2>L </h2>
-<a href="backend.Linear.html#Lcall">Lcall</a> [in <a href="backend.Linear.html">backend.Linear</a>]<br/>
-<a href="backend.Linear.html#Lcond">Lcond</a> [in <a href="backend.Linear.html">backend.Linear</a>]<br/>
-<a href="lib.Maps.html#Leaf">Leaf</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Inclusion.html#leaf">leaf</a> [in <a href="lib.Inclusion.html">lib.Inclusion</a>]<br/>
-<a href="backend.Linear.html#Lgetstack">Lgetstack</a> [in <a href="backend.Linear.html">backend.Linear</a>]<br/>
-<a href="backend.Linear.html#Lgoto">Lgoto</a> [in <a href="backend.Linear.html">backend.Linear</a>]<br/>
-<a href="lib.Coqlib.html#list_forall2_cons">list_forall2_cons</a> [in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#list_forall2_nil">list_forall2_nil</a> [in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#list_norepet_cons">list_norepet_cons</a> [in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#list_norepet_nil">list_norepet_nil</a> [in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="backend.Linear.html#Llabel">Llabel</a> [in <a href="backend.Linear.html">backend.Linear</a>]<br/>
-<a href="backend.Linear.html#Lload">Lload</a> [in <a href="backend.Linear.html">backend.Linear</a>]<br/>
-<a href="backend.CSE.html#Load">Load</a> [in <a href="backend.CSE.html">backend.CSE</a>]<br/>
-<a href="backend.Locations.html#Local">Local</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Linear.html#Lop">Lop</a> [in <a href="backend.Linear.html">backend.Linear</a>]<br/>
-<a href="backend.PPC.html#LR">LR</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.Linear.html#Lreturn">Lreturn</a> [in <a href="backend.Linear.html">backend.Linear</a>]<br/>
-<a href="backend.Linear.html#Lsetstack">Lsetstack</a> [in <a href="backend.Linear.html">backend.Linear</a>]<br/>
-<a href="backend.Linear.html#Lstore">Lstore</a> [in <a href="backend.Linear.html">backend.Linear</a>]<br/>
-<a href="backend.Csharpminor.html#LVarray">LVarray</a> [in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Csharpminor.html#LVscalar">LVscalar</a> [in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<br/><br/><a name="constructor_M"></a><h2>M </h2>
-<a href="backend.Mach.html#Mcall">Mcall</a> [in <a href="backend.Mach.html">backend.Mach</a>]<br/>
-<a href="backend.Mach.html#Mcond">Mcond</a> [in <a href="backend.Mach.html">backend.Mach</a>]<br/>
-<a href="backend.Cminorgenproof.html#mcs_cons">mcs_cons</a> [in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#mcs_nil">mcs_nil</a> [in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.AST.html#Mfloat32">Mfloat32</a> [in <a href="backend.AST.html">backend.AST</a>]<br/>
-<a href="backend.AST.html#Mfloat64">Mfloat64</a> [in <a href="backend.AST.html">backend.AST</a>]<br/>
-<a href="backend.Mach.html#Mgetparam">Mgetparam</a> [in <a href="backend.Mach.html">backend.Mach</a>]<br/>
-<a href="backend.Mach.html#Mgetstack">Mgetstack</a> [in <a href="backend.Mach.html">backend.Mach</a>]<br/>
-<a href="backend.Mach.html#Mgoto">Mgoto</a> [in <a href="backend.Mach.html">backend.Mach</a>]<br/>
-<a href="backend.AST.html#Mint16signed">Mint16signed</a> [in <a href="backend.AST.html">backend.AST</a>]<br/>
-<a href="backend.AST.html#Mint16unsigned">Mint16unsigned</a> [in <a href="backend.AST.html">backend.AST</a>]<br/>
-<a href="backend.AST.html#Mint32">Mint32</a> [in <a href="backend.AST.html">backend.AST</a>]<br/>
-<a href="backend.AST.html#Mint8signed">Mint8signed</a> [in <a href="backend.AST.html">backend.AST</a>]<br/>
-<a href="backend.AST.html#Mint8unsigned">Mint8unsigned</a> [in <a href="backend.AST.html">backend.AST</a>]<br/>
-<a href="backend.Mach.html#Mlabel">Mlabel</a> [in <a href="backend.Mach.html">backend.Mach</a>]<br/>
-<a href="backend.Mach.html#Mload">Mload</a> [in <a href="backend.Mach.html">backend.Mach</a>]<br/>
-<a href="backend.Mach.html#Mop">Mop</a> [in <a href="backend.Mach.html">backend.Mach</a>]<br/>
-<a href="backend.Mach.html#Mreturn">Mreturn</a> [in <a href="backend.Mach.html">backend.Mach</a>]<br/>
-<a href="backend.Mach.html#Msetstack">Msetstack</a> [in <a href="backend.Mach.html">backend.Mach</a>]<br/>
-<a href="backend.Mach.html#Mstore">Mstore</a> [in <a href="backend.Mach.html">backend.Mach</a>]<br/>
-<a href="backend.Cmconstr.html#mulimm_case1">mulimm_case1</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#mulimm_case2">mulimm_case2</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#mulimm_default">mulimm_default</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#mul_case1">mul_case1</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#mul_case2">mul_case2</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#mul_default">mul_default</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<br/><br/><a name="constructor_N"></a><h2>N </h2>
-<a href="backend.Op.html#n">n</a> [in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="lib.Maps.html#Node">Node</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Inclusion.html#node">node</a> [in <a href="lib.Inclusion.html">lib.Inclusion</a>]<br/>
-<a href="backend.Locations.html#norepet_cons">norepet_cons</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#norepet_nil">norepet_nil</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Cmconstr.html#notint_case1">notint_case1</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#notint_case2">notint_case2</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#notint_case3">notint_case3</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#notint_default">notint_default</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Machabstr2mach.html#notin_callstack_cons">notin_callstack_cons</a> [in <a href="backend.Machabstr2mach.html">backend.Machabstr2mach</a>]<br/>
-<a href="backend.Machabstr2mach.html#notin_callstack_nil">notin_callstack_nil</a> [in <a href="backend.Machabstr2mach.html">backend.Machabstr2mach</a>]<br/>
-<a href="backend.Constprop.html#Novalue">Novalue</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<br/><br/><a name="constructor_O"></a><h2>O </h2>
-<a href="backend.Op.html#Oabsf">Oabsf</a> [in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Csharpminor.html#Oabsf">Oabsf</a> [in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Csharpminor.html#Oadd">Oadd</a> [in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Op.html#Oadd">Oadd</a> [in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Csharpminor.html#Oaddf">Oaddf</a> [in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Op.html#Oaddf">Oaddf</a> [in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Op.html#Oaddimm">Oaddimm</a> [in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Op.html#Oaddrstack">Oaddrstack</a> [in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Op.html#Oaddrsymbol">Oaddrsymbol</a> [in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Op.html#Oand">Oand</a> [in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Csharpminor.html#Oand">Oand</a> [in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Op.html#Oandimm">Oandimm</a> [in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Csharpminor.html#Ocast16signed">Ocast16signed</a> [in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Op.html#Ocast16signed">Ocast16signed</a> [in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Csharpminor.html#Ocast16unsigned">Ocast16unsigned</a> [in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Csharpminor.html#Ocast8signed">Ocast8signed</a> [in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Op.html#Ocast8signed">Ocast8signed</a> [in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Csharpminor.html#Ocast8unsigned">Ocast8unsigned</a> [in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Op.html#Ocmp">Ocmp</a> [in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Csharpminor.html#Ocmp">Ocmp</a> [in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Csharpminor.html#Ocmpf">Ocmpf</a> [in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Csharpminor.html#Ocmpu">Ocmpu</a> [in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Op.html#Odiv">Odiv</a> [in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Csharpminor.html#Odiv">Odiv</a> [in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Op.html#Odivf">Odivf</a> [in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Csharpminor.html#Odivf">Odivf</a> [in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Csharpminor.html#Odivu">Odivu</a> [in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Op.html#Odivu">Odivu</a> [in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Op.html#Ofloatconst">Ofloatconst</a> [in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Csharpminor.html#Ofloatconst">Ofloatconst</a> [in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Op.html#Ofloatofint">Ofloatofint</a> [in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Csharpminor.html#Ofloatofint">Ofloatofint</a> [in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Csharpminor.html#Ofloatofintu">Ofloatofintu</a> [in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Op.html#Ofloatofintu">Ofloatofintu</a> [in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Csharpminor.html#Ointconst">Ointconst</a> [in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Op.html#Ointconst">Ointconst</a> [in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Csharpminor.html#Ointoffloat">Ointoffloat</a> [in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Op.html#Ointoffloat">Ointoffloat</a> [in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.RTLgen.html#OK">OK</a> [in <a href="backend.RTLgen.html">backend.RTLgen</a>]<br/>
-<a href="backend.PPC.html#OK">OK</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.Csharpminor.html#Omod">Omod</a> [in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Csharpminor.html#Omodu">Omodu</a> [in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Op.html#Omove">Omove</a> [in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Csharpminor.html#Omul">Omul</a> [in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Op.html#Omul">Omul</a> [in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Op.html#Omuladdf">Omuladdf</a> [in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Op.html#Omulf">Omulf</a> [in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Csharpminor.html#Omulf">Omulf</a> [in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Op.html#Omulimm">Omulimm</a> [in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Op.html#Omulsubf">Omulsubf</a> [in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Op.html#Onand">Onand</a> [in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Csharpminor.html#Onegf">Onegf</a> [in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Op.html#Onegf">Onegf</a> [in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Op.html#Onor">Onor</a> [in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Csharpminor.html#Onotint">Onotint</a> [in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Op.html#Onxor">Onxor</a> [in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Op.html#Oor">Oor</a> [in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Csharpminor.html#Oor">Oor</a> [in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Op.html#Oorimm">Oorimm</a> [in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.CSE.html#Op">Op</a> [in <a href="backend.CSE.html">backend.CSE</a>]<br/>
-<a href="backend.Constprop.html#op_strength_reduction_case1">op_strength_reduction_case1</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#op_strength_reduction_case10">op_strength_reduction_case10</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#op_strength_reduction_case11">op_strength_reduction_case11</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#op_strength_reduction_case12">op_strength_reduction_case12</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#op_strength_reduction_case2">op_strength_reduction_case2</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#op_strength_reduction_case3">op_strength_reduction_case3</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#op_strength_reduction_case4">op_strength_reduction_case4</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#op_strength_reduction_case5">op_strength_reduction_case5</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#op_strength_reduction_case6">op_strength_reduction_case6</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#op_strength_reduction_case7">op_strength_reduction_case7</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#op_strength_reduction_case8">op_strength_reduction_case8</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#op_strength_reduction_case9">op_strength_reduction_case9</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#op_strength_reduction_default">op_strength_reduction_default</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Op.html#Orolm">Orolm</a> [in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Cmconstr.html#or_case1">or_case1</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#or_default">or_default</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Csharpminor.html#Oshl">Oshl</a> [in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Op.html#Oshl">Oshl</a> [in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Op.html#Oshr">Oshr</a> [in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Csharpminor.html#Oshr">Oshr</a> [in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Op.html#Oshrimm">Oshrimm</a> [in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Op.html#Oshru">Oshru</a> [in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Csharpminor.html#Oshru">Oshru</a> [in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Op.html#Oshrximm">Oshrximm</a> [in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Op.html#Osingleoffloat">Osingleoffloat</a> [in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Csharpminor.html#Osingleoffloat">Osingleoffloat</a> [in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Csharpminor.html#Osub">Osub</a> [in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Op.html#Osub">Osub</a> [in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Csharpminor.html#Osubf">Osubf</a> [in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Op.html#Osubf">Osubf</a> [in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Op.html#Osubimm">Osubimm</a> [in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Op.html#Oundef">Oundef</a> [in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Locations.html#Outgoing">Outgoing</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Csharpminor.html#Out_exit">Out_exit</a> [in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Cminor.html#Out_exit">Out_exit</a> [in <a href="backend.Cminor.html">backend.Cminor</a>]<br/>
-<a href="backend.Cminor.html#Out_normal">Out_normal</a> [in <a href="backend.Cminor.html">backend.Cminor</a>]<br/>
-<a href="backend.Csharpminor.html#Out_normal">Out_normal</a> [in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Cminor.html#Out_return">Out_return</a> [in <a href="backend.Cminor.html">backend.Cminor</a>]<br/>
-<a href="backend.Csharpminor.html#Out_return">Out_return</a> [in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Op.html#Oxor">Oxor</a> [in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Csharpminor.html#Oxor">Oxor</a> [in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Op.html#Oxorimm">Oxorimm</a> [in <a href="backend.Op.html">backend.Op</a>]<br/>
-<br/><br/><a name="constructor_P"></a><h2>P </h2>
-<a href="backend.PPC.html#Padd">Padd</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Paddi">Paddi</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Paddis">Paddis</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Paddze">Paddze</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pallocframe">Pallocframe</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pandc">Pandc</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pandis_">Pandis_</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pandi_">Pandi_</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pand_">Pand_</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pb">Pb</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pbctr">Pbctr</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pbctrl">Pbctrl</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pbf">Pbf</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pbl">Pbl</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pblr">Pblr</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pbt">Pbt</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#PC">PC</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pcmplw">Pcmplw</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pcmplwi">Pcmplwi</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pcmpw">Pcmpw</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pcmpwi">Pcmpwi</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pcror">Pcror</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pdivw">Pdivw</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pdivwu">Pdivwu</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Peqv">Peqv</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pextsb">Pextsb</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pextsh">Pextsh</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pfabs">Pfabs</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pfadd">Pfadd</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pfcmpu">Pfcmpu</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pfcti">Pfcti</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pfdiv">Pfdiv</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pfmadd">Pfmadd</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pfmr">Pfmr</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pfmsub">Pfmsub</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pfmul">Pfmul</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pfneg">Pfneg</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pfreeframe">Pfreeframe</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pfrsp">Pfrsp</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pfsub">Pfsub</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pfundef">Pfundef</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pictf">Pictf</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Piuctf">Piuctf</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Piundef">Piundef</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Plabel">Plabel</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Plbz">Plbz</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Plbzx">Plbzx</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Plfd">Plfd</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Plfdx">Plfdx</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Plfi">Plfi</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Plfs">Plfs</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Plfsx">Plfsx</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Plha">Plha</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Plhax">Plhax</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Plhz">Plhz</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Plhzx">Plhzx</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Plwz">Plwz</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Plwzx">Plwzx</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pmfcrbit">Pmfcrbit</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pmflr">Pmflr</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pmr">Pmr</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pmtctr">Pmtctr</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pmtlr">Pmtlr</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pmulli">Pmulli</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pmullw">Pmullw</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pnand">Pnand</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pnor">Pnor</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Por">Por</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Porc">Porc</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pori">Pori</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Poris">Poris</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Prlwinm">Prlwinm</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pslw">Pslw</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Psraw">Psraw</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Psrawi">Psrawi</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Psrw">Psrw</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pstb">Pstb</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pstbx">Pstbx</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pstfd">Pstfd</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pstfdx">Pstfdx</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pstfs">Pstfs</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pstfsx">Pstfsx</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Psth">Psth</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Psthx">Psthx</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pstw">Pstw</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pstwx">Pstwx</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Psubfc">Psubfc</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Psubfic">Psubfic</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pxor">Pxor</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pxori">Pxori</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pxoris">Pxoris</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<br/><br/><a name="constructor_R"></a><h2>R </h2>
-<a href="backend.Locations.html#R">R</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.LTL.html#Return">Return</a> [in <a href="backend.LTL.html">backend.LTL</a>]<br/>
-<a href="backend.RTLgenproof1.html#return_reg_ok_none">return_reg_ok_none</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#return_reg_ok_some">return_reg_ok_some</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="lib.Integers.html#RLW_Sbad">RLW_Sbad</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#RLW_S0">RLW_S0</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#RLW_S1">RLW_S1</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#RLW_S2">RLW_S2</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#RLW_S3">RLW_S3</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#RLW_S4">RLW_S4</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#RLW_S5">RLW_S5</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#RLW_S6">RLW_S6</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Cmconstr.html#rolm_case1">rolm_case1</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#rolm_case2">rolm_case2</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#rolm_default">rolm_default</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Locations.html#R10">R10</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#R13">R13</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#R14">R14</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#R15">R15</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#R16">R16</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#R17">R17</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#R18">R18</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#R19">R19</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Op.html#r2">r2</a> [in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Op.html#r2">r2</a> [in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Locations.html#R20">R20</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#R21">R21</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#R22">R22</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#R23">R23</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#R24">R24</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#R25">R25</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#R26">R26</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#R27">R27</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#R28">R28</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#R29">R29</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#R3">R3</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#R30">R30</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#R31">R31</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#R4">R4</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#R5">R5</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#R6">R6</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#R7">R7</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#R8">R8</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#R9">R9</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<br/><br/><a name="constructor_S"></a><h2>S </h2>
-<a href="backend.Locations.html#S">S</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Cminor.html#Sblock">Sblock</a> [in <a href="backend.Cminor.html">backend.Cminor</a>]<br/>
-<a href="backend.Csharpminor.html#Sblock">Sblock</a> [in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Cminor.html#Scons">Scons</a> [in <a href="backend.Cminor.html">backend.Cminor</a>]<br/>
-<a href="backend.Csharpminor.html#Scons">Scons</a> [in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Machabstr.html#set_slot_intro">set_slot_intro</a> [in <a href="backend.Machabstr.html">backend.Machabstr</a>]<br/>
-<a href="backend.Cminor.html#Sexit">Sexit</a> [in <a href="backend.Cminor.html">backend.Cminor</a>]<br/>
-<a href="backend.Csharpminor.html#Sexit">Sexit</a> [in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Cminor.html#Sexpr">Sexpr</a> [in <a href="backend.Cminor.html">backend.Cminor</a>]<br/>
-<a href="backend.Csharpminor.html#Sexpr">Sexpr</a> [in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Cmconstr.html#shift_case1">shift_case1</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#shift_default">shift_default</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Csharpminor.html#Sifthenelse">Sifthenelse</a> [in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Cminor.html#Sifthenelse">Sifthenelse</a> [in <a href="backend.Cminor.html">backend.Cminor</a>]<br/>
-<a href="backend.Mem.html#Size16">Size16</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#Size32">Size32</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#Size64">Size64</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#Size8">Size8</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Csharpminor.html#Sloop">Sloop</a> [in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Cminor.html#Sloop">Sloop</a> [in <a href="backend.Cminor.html">backend.Cminor</a>]<br/>
-<a href="backend.Csharpminor.html#Snil">Snil</a> [in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Cminor.html#Snil">Snil</a> [in <a href="backend.Cminor.html">backend.Cminor</a>]<br/>
-<a href="backend.Csharpminor.html#Sreturn">Sreturn</a> [in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Cminor.html#Sreturn">Sreturn</a> [in <a href="backend.Cminor.html">backend.Cminor</a>]<br/>
-<a href="backend.RTLgenproof1.html#state_incr_intro">state_incr_intro</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.Parallelmove.html#stepp_refl">stepp_refl</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#stepp_trans">stepp_trans</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#step_loop">step_loop</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#step_nop">step_nop</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#step_pop">step_pop</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#step_push">step_push</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#step_start">step_start</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Cmconstr.html#subf_case1">subf_case1</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#subf_default">subf_default</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#sub_case1">sub_case1</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#sub_case2">sub_case2</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#sub_case3">sub_case3</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#sub_case4">sub_case4</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#sub_default">sub_default</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<br/><br/><a name="constructor_T"></a><h2>T </h2>
-<a href="backend.RTLgenproof1.html#target_regs_cons">target_regs_cons</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#target_regs_nil">target_regs_nil</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#target_reg_immut_var">target_reg_immut_var</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.AST.html#Tfloat">Tfloat</a> [in <a href="backend.AST.html">backend.AST</a>]<br/>
-<a href="backend.AST.html#Tint">Tint</a> [in <a href="backend.AST.html">backend.AST</a>]<br/>
-<a href="backend.RTLtyping.html#tReg">tReg</a> [in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.RTLtyping.html#tTy">tTy</a> [in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<br/><br/><a name="constructor_U"></a><h2>U </h2>
-<a href="backend.Mem.html#Undef">Undef</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<br/><br/><a name="constructor_V"></a><h2>V </h2>
-<a href="backend.Mem.html#val_cons_inject">val_cons_inject</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#val_content_inject_base">val_content_inject_base</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#val_content_inject_8">val_content_inject_8</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#val_inject_float">val_inject_float</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#val_inject_int">val_inject_int</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#val_inject_ptr">val_inject_ptr</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#val_nil_inject">val_nil_inject</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Cminorgenproof.html#vars_vals_cons">vars_vals_cons</a> [in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#vars_vals_nil">vars_vals_nil</a> [in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Cminorgen.html#Var_global">Var_global</a> [in <a href="backend.Cminorgen.html">backend.Cminorgen</a>]<br/>
-<a href="backend.Cminorgen.html#Var_local">Var_local</a> [in <a href="backend.Cminorgen.html">backend.Cminorgen</a>]<br/>
-<a href="backend.Cminorgen.html#Var_stack_array">Var_stack_array</a> [in <a href="backend.Cminorgen.html">backend.Cminorgen</a>]<br/>
-<a href="backend.Cminorgen.html#Var_stack_scalar">Var_stack_scalar</a> [in <a href="backend.Cminorgen.html">backend.Cminorgen</a>]<br/>
-<a href="backend.Values.html#Vfloat">Vfloat</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Values.html#Vint">Vint</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Constpropproof.html#vlma_cons">vlma_cons</a> [in <a href="backend.Constpropproof.html">backend.Constpropproof</a>]<br/>
-<a href="backend.Constpropproof.html#vlma_nil">vlma_nil</a> [in <a href="backend.Constpropproof.html">backend.Constpropproof</a>]<br/>
-<a href="backend.Values.html#Vptr">Vptr</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Values.html#Vundef">Vundef</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<br/><br/><a name="constructor_W"></a><h2>W </h2>
-<a href="backend.LTLtyping.html#wt_Bgetstack">wt_Bgetstack</a> [in <a href="backend.LTLtyping.html">backend.LTLtyping</a>]<br/>
-<a href="backend.LTLtyping.html#wt_Bop">wt_Bop</a> [in <a href="backend.LTLtyping.html">backend.LTLtyping</a>]<br/>
-<a href="backend.LTLtyping.html#wt_Bopmove">wt_Bopmove</a> [in <a href="backend.LTLtyping.html">backend.LTLtyping</a>]<br/>
-<a href="backend.LTLtyping.html#wt_Bopundef">wt_Bopundef</a> [in <a href="backend.LTLtyping.html">backend.LTLtyping</a>]<br/>
-<a href="backend.LTLtyping.html#wt_Bsetstack">wt_Bsetstack</a> [in <a href="backend.LTLtyping.html">backend.LTLtyping</a>]<br/>
-<a href="backend.RTLtyping.html#wt_Inop">wt_Inop</a> [in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.RTLtyping.html#wt_Iop">wt_Iop</a> [in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.RTLtyping.html#wt_Iopmove">wt_Iopmove</a> [in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.RTLtyping.html#wt_Iopundef">wt_Iopundef</a> [in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.Lineartyping.html#wt_Lgetstack">wt_Lgetstack</a> [in <a href="backend.Lineartyping.html">backend.Lineartyping</a>]<br/>
-<a href="backend.Lineartyping.html#wt_Lop">wt_Lop</a> [in <a href="backend.Lineartyping.html">backend.Lineartyping</a>]<br/>
-<a href="backend.Lineartyping.html#wt_Lopmove">wt_Lopmove</a> [in <a href="backend.Lineartyping.html">backend.Lineartyping</a>]<br/>
-<a href="backend.Lineartyping.html#wt_Lopundef">wt_Lopundef</a> [in <a href="backend.Lineartyping.html">backend.Lineartyping</a>]<br/>
-<a href="backend.Lineartyping.html#wt_Lsetstack">wt_Lsetstack</a> [in <a href="backend.Lineartyping.html">backend.Lineartyping</a>]<br/>
-<a href="backend.Machtyping.html#wt_Mgetstack">wt_Mgetstack</a> [in <a href="backend.Machtyping.html">backend.Machtyping</a>]<br/>
-<a href="backend.Machtyping.html#wt_Mlabel">wt_Mlabel</a> [in <a href="backend.Machtyping.html">backend.Machtyping</a>]<br/>
-<a href="backend.Machtyping.html#wt_Msetstack">wt_Msetstack</a> [in <a href="backend.Machtyping.html">backend.Machtyping</a>]<br/>
-<br/><br/><a name="constructor__"></a><h2>_ </h2>
-<a href="backend.Lineartyping.html#_">_</a> [in <a href="backend.Lineartyping.html">backend.Lineartyping</a>]<br/>
-<a href="backend.LTLtyping.html#_">_</a> [in <a href="backend.LTLtyping.html">backend.LTLtyping</a>]<br/>
-<br/><br/><hr/>
-<h1>Inductive Index</h1>
-<a name="inductive_A"></a><h2>A </h2>
-<a href="backend.Op.html#a">a</a> [in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Op.html#a">a</a> [in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Cmconstr.html#addf_cases">addf_cases</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#addimm_cases">addimm_cases</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Op.html#addressing">addressing</a> [in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Cmconstr.html#addressing_cases">addressing_cases</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Constprop.html#addr_strength_reduction_cases">addr_strength_reduction_cases</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Cmconstr.html#add_cases">add_cases</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Stackingproof.html#agree">agree</a> [in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="backend.Csharpminor.html#alloc_variables">alloc_variables</a> [in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Constprop.html#approx">approx</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<br/><br/><a name="inductive_B"></a><h2>B </h2>
-<a href="lib.Inclusion.html#bin">bin</a> [in <a href="lib.Inclusion.html">lib.Inclusion</a>]<br/>
-<a href="backend.Csharpminor.html#bind_parameters">bind_parameters</a> [in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.LTL.html#block">block</a> [in <a href="backend.LTL.html">backend.LTL</a>]<br/>
-<a href="backend.Mem.html#block_contents">block_contents</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#block_contents_inject">block_contents_inject</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Values.html#bool_of_val">bool_of_val</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Lineartyping.html#bounds">bounds</a> [in <a href="backend.Lineartyping.html">backend.Lineartyping</a>]<br/>
-<br/><br/><a name="inductive_C"></a><h2>C </h2>
-<a href="backend.Machabstr2mach.html#callstack_dom">callstack_dom</a> [in <a href="backend.Machabstr2mach.html">backend.Machabstr2mach</a>]<br/>
-<a href="backend.Machabstr2mach.html#callstack_invariant">callstack_invariant</a> [in <a href="backend.Machabstr2mach.html">backend.Machabstr2mach</a>]<br/>
-<a href="backend.Machabstr2mach.html#callstack_linked">callstack_linked</a> [in <a href="backend.Machabstr2mach.html">backend.Machabstr2mach</a>]<br/>
-<a href="backend.AST.html#comparison">comparison</a> [in <a href="backend.AST.html">backend.AST</a>]<br/>
-<a href="backend.Cminor.html#condexpr">condexpr</a> [in <a href="backend.Cminor.html">backend.Cminor</a>]<br/>
-<a href="backend.Op.html#condition">condition</a> [in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Constprop.html#cond_strength_reduction_cases">cond_strength_reduction_cases</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.PPC.html#constant">constant</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.Mem.html#content">content</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#content_inject">content_inject</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Linearizeproof.html#cont_for_outcome">cont_for_outcome</a> [in <a href="backend.Linearizeproof.html">backend.Linearizeproof</a>]<br/>
-<a href="backend.PPC.html#crbit">crbit</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<br/><br/><a name="inductive_D"></a><h2>D </h2>
-<a href="backend.Cmconstr.html#divu_cases">divu_cases</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Parallelmove.html#dstep">dstep</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#dstepp">dstepp</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<br/><br/><a name="inductive_E"></a><h2>E </h2>
-<a href="backend.Csharpminor.html#eval_expr">eval_expr</a> [in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Cminor.html#eval_expr">eval_expr</a> [in <a href="backend.Cminor.html">backend.Cminor</a>]<br/>
-<a href="backend.Constprop.html#eval_static_condition_cases">eval_static_condition_cases</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_operation_cases">eval_static_operation_cases</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Machabstr.html#exec_instr">exec_instr</a> [in <a href="backend.Machabstr.html">backend.Machabstr</a>]<br/>
-<a href="backend.RTL.html#exec_instr">exec_instr</a> [in <a href="backend.RTL.html">backend.RTL</a>]<br/>
-<a href="backend.LTL.html#exec_instr">exec_instr</a> [in <a href="backend.LTL.html">backend.LTL</a>]<br/>
-<a href="backend.Linear.html#exec_instr">exec_instr</a> [in <a href="backend.Linear.html">backend.Linear</a>]<br/>
-<a href="backend.Mach.html#exec_instr">exec_instr</a> [in <a href="backend.Mach.html">backend.Mach</a>]<br/>
-<a href="backend.PPC.html#exec_step">exec_step</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#exec_steps">exec_steps</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPCgenproof1.html#exec_straight">exec_straight</a> [in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.Csharpminor.html#expr">expr</a> [in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Cminor.html#expr">expr</a> [in <a href="backend.Cminor.html">backend.Cminor</a>]<br/>
-<a href="backend.Csharpminor.html#exprlist">exprlist</a> [in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Cminor.html#exprlist">exprlist</a> [in <a href="backend.Cminor.html">backend.Cminor</a>]<br/>
-<br/><br/><a name="inductive_F"></a><h2>F </h2>
-<a href="backend.Cminorgenproof.html#frame">frame</a> [in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Stacking.html#frame_env">frame_env</a> [in <a href="backend.Stacking.html">backend.Stacking</a>]<br/>
-<a href="backend.Stacking.html#frame_index">frame_index</a> [in <a href="backend.Stacking.html">backend.Stacking</a>]<br/>
-<a href="backend.Machabstr2mach.html#frame_match">frame_match</a> [in <a href="backend.Machabstr2mach.html">backend.Machabstr2mach</a>]<br/>
-<a href="backend.PPC.html#freg">freg</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.Mach.html#function">function</a> [in <a href="backend.Mach.html">backend.Mach</a>]<br/>
-<a href="backend.Csharpminor.html#function">function</a> [in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.RTL.html#function">function</a> [in <a href="backend.RTL.html">backend.RTL</a>]<br/>
-<a href="backend.LTL.html#function">function</a> [in <a href="backend.LTL.html">backend.LTL</a>]<br/>
-<a href="backend.Cminor.html#function">function</a> [in <a href="backend.Cminor.html">backend.Cminor</a>]<br/>
-<a href="backend.Linear.html#function">function</a> [in <a href="backend.Linear.html">backend.Linear</a>]<br/>
-<br/><br/><a name="inductive_G"></a><h2>G </h2>
-<a href="backend.Globalenvs.html#genv">genv</a> [in <a href="backend.Globalenvs.html">backend.Globalenvs</a>]<br/>
-<a href="backend.Machabstr.html#get_slot">get_slot</a> [in <a href="backend.Machabstr.html">backend.Machabstr</a>]<br/>
-<a href="backend.InterfGraph.html#graph">graph</a> [in <a href="backend.InterfGraph.html">backend.InterfGraph</a>]<br/>
-<br/><br/><a name="inductive_I"></a><h2>I </h2>
-<a href="backend.PPC.html#immediate">immediate</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#immediate">immediate</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#immediate">immediate</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#immediate">immediate</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#immediate">immediate</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#immediate">immediate</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.LTLtyping.html#Incoming">Incoming</a> [in <a href="backend.LTLtyping.html">backend.LTLtyping</a>]<br/>
-<a href="backend.Lineartyping.html#Incoming">Incoming</a> [in <a href="backend.Lineartyping.html">backend.Lineartyping</a>]<br/>
-<a href="backend.Cmconstrproof.html#insert_lenv">insert_lenv</a> [in <a href="backend.Cmconstrproof.html">backend.Cmconstrproof</a>]<br/>
-<a href="backend.Linear.html#instruction">instruction</a> [in <a href="backend.Linear.html">backend.Linear</a>]<br/>
-<a href="backend.PPC.html#instruction">instruction</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.RTL.html#instruction">instruction</a> [in <a href="backend.RTL.html">backend.RTL</a>]<br/>
-<a href="backend.Mach.html#instruction">instruction</a> [in <a href="backend.Mach.html">backend.Mach</a>]<br/>
-<a href="lib.Integers.html#int">int</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.PPC.html#ireg">ireg</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.Linearizeproof.html#is_tail">is_tail</a> [in <a href="backend.Linearizeproof.html">backend.Linearizeproof</a>]<br/>
-<br/><br/><a name="inductive_L"></a><h2>L </h2>
-<a href="lib.Coqlib.html#list_forall2">list_forall2</a> [in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#list_norepet">list_norepet</a> [in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="backend.Locations.html#loc">loc</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Csharpminor.html#local_variable">local_variable</a> [in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<br/><br/><a name="inductive_M"></a><h2>M </h2>
-<a href="backend.RTLgen.html#mapping">mapping</a> [in <a href="backend.RTLgen.html">backend.RTLgen</a>]<br/>
-<a href="backend.RTLgenproof1.html#map_wf">map_wf</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.Cminorgenproof.html#match_callstack">match_callstack</a> [in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#match_env">match_env</a> [in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.RTLgenproof1.html#match_env">match_env</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.Cminorgenproof.html#match_globalenvs">match_globalenvs</a> [in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#match_var">match_var</a> [in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Mem.html#mem">mem</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.AST.html#memory_chunk">memory_chunk</a> [in <a href="backend.AST.html">backend.AST</a>]<br/>
-<a href="backend.Mem.html#memory_size">memory_size</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#mem_inject">mem_inject</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Locations.html#mreg">mreg</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Cmconstr.html#mulimm_cases">mulimm_cases</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#mul_cases">mul_cases</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.RTLtyping.html#myT">myT</a> [in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<br/><br/><a name="inductive_N"></a><h2>N </h2>
-<a href="backend.Locations.html#norepet">norepet</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Cmconstr.html#notint_cases">notint_cases</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Machabstr2mach.html#notin_callstack">notin_callstack</a> [in <a href="backend.Machabstr2mach.html">backend.Machabstr2mach</a>]<br/>
-<a href="backend.CSE.html#numbering">numbering</a> [in <a href="backend.CSE.html">backend.CSE</a>]<br/>
-<br/><br/><a name="inductive_O"></a><h2>O </h2>
-<a href="backend.Csharpminor.html#operation">operation</a> [in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Op.html#operation">operation</a> [in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Constprop.html#op_strength_reduction_cases">op_strength_reduction_cases</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Cmconstr.html#or_cases">or_cases</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cminor.html#outcome">outcome</a> [in <a href="backend.Cminor.html">backend.Cminor</a>]<br/>
-<a href="backend.LTL.html#outcome">outcome</a> [in <a href="backend.LTL.html">backend.LTL</a>]<br/>
-<a href="backend.PPC.html#outcome">outcome</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.Csharpminor.html#outcome">outcome</a> [in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Cminorgenproof.html#outcome_inject">outcome_inject</a> [in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<br/><br/><a name="inductive_P"></a><h2>P </h2>
-<a href="backend.PPC.html#preg">preg</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.AST.html#program">program</a> [in <a href="backend.AST.html">backend.AST</a>]<br/>
-<br/><br/><a name="inductive_R"></a><h2>R </h2>
-<a href="backend.RTLgen.html#res">res</a> [in <a href="backend.RTLgen.html">backend.RTLgen</a>]<br/>
-<a href="backend.RTLgenproof1.html#return_reg_ok">return_reg_ok</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.CSE.html#rhs">rhs</a> [in <a href="backend.CSE.html">backend.CSE</a>]<br/>
-<a href="lib.Integers.html#rlw_state">rlw_state</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Cmconstr.html#rolm_cases">rolm_cases</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<br/><br/><a name="inductive_S"></a><h2>S </h2>
-<a href="backend.Machabstr.html#set_slot">set_slot</a> [in <a href="backend.Machabstr.html">backend.Machabstr</a>]<br/>
-<a href="backend.Cmconstr.html#shift_cases">shift_cases</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.AST.html#signature">signature</a> [in <a href="backend.AST.html">backend.AST</a>]<br/>
-<a href="backend.Locations.html#slot">slot</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Kildall.html#state">state</a> [in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.RTLgen.html#state">state</a> [in <a href="backend.RTLgen.html">backend.RTLgen</a>]<br/>
-<a href="backend.Kildall.html#state">state</a> [in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.RTLgenproof1.html#state_incr">state_incr</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.Parallelmove.html#step">step</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#stepp">stepp</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Csharpminor.html#stmt">stmt</a> [in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Cminor.html#stmt">stmt</a> [in <a href="backend.Cminor.html">backend.Cminor</a>]<br/>
-<a href="backend.Csharpminor.html#stmtlist">stmtlist</a> [in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Cminor.html#stmtlist">stmtlist</a> [in <a href="backend.Cminor.html">backend.Cminor</a>]<br/>
-<a href="backend.Cmconstr.html#subf_cases">subf_cases</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#sub_cases">sub_cases</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<br/><br/><a name="inductive_T"></a><h2>T </h2>
-<a href="backend.RTLgenproof1.html#target_regs_ok">target_regs_ok</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#target_reg_ok">target_reg_ok</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.PPCgenproof.html#transl_code_at_pc">transl_code_at_pc</a> [in <a href="backend.PPCgenproof.html">backend.PPCgenproof</a>]<br/>
-<a href="lib.Maps.html#tree">tree</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="backend.AST.html#typ">typ</a> [in <a href="backend.AST.html">backend.AST</a>]<br/>
-<a href="lib.Lattice.html#t_">t_</a> [in <a href="lib.Lattice.html">lib.Lattice</a>]<br/>
-<a href="lib.Lattice.html#t_">t_</a> [in <a href="lib.Lattice.html">lib.Lattice</a>]<br/>
-<br/><br/><a name="inductive_U"></a><h2>U </h2>
-<a href="lib.union_find.html#unionfind">unionfind</a> [in <a href="lib.union_find.html">lib.union_find</a>]<br/>
-<br/><br/><a name="inductive_V"></a><h2>V </h2>
-<a href="backend.Values.html#val">val</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Mem.html#val_content_inject">val_content_inject</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#val_inject">val_inject</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#val_list_inject">val_list_inject</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Constpropproof.html#val_list_match_approx">val_list_match_approx</a> [in <a href="backend.Constpropproof.html">backend.Constpropproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#vars_vals_match">vars_vals_match</a> [in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Cminorgen.html#var_info">var_info</a> [in <a href="backend.Cminorgen.html">backend.Cminorgen</a>]<br/>
-<br/><br/><a name="inductive_W"></a><h2>W </h2>
-<a href="backend.LTLtyping.html#wt_block">wt_block</a> [in <a href="backend.LTLtyping.html">backend.LTLtyping</a>]<br/>
-<a href="backend.RTLtyping.html#wt_function">wt_function</a> [in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.Machtyping.html#wt_function">wt_function</a> [in <a href="backend.Machtyping.html">backend.Machtyping</a>]<br/>
-<a href="backend.Lineartyping.html#wt_instr">wt_instr</a> [in <a href="backend.Lineartyping.html">backend.Lineartyping</a>]<br/>
-<a href="backend.Machtyping.html#wt_instr">wt_instr</a> [in <a href="backend.Machtyping.html">backend.Machtyping</a>]<br/>
-<a href="backend.RTLtyping.html#wt_instr">wt_instr</a> [in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<br/><br/><hr/>
-<h1>Definition Index</h1>
-<a name="definition_A"></a><h2>A </h2>
-<a href="backend.Values.html#absf">absf</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Cmconstr.html#absfloat">absfloat</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Values.html#add">add</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="lib.Sets.html#add">add</a> [in <a href="lib.Sets.html">lib.Sets</a>]<br/>
-<a href="backend.Cmconstr.html#add">add</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.RTLtyping.html#add">add</a> [in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="lib.Integers.html#add">add</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Cmconstr.html#addf">addf</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Values.html#addf">addf</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Cmconstr.html#addf_match">addf_match</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#addf_match_aux">addf_match_aux</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.PPCgen.html#addimm">addimm</a> [in <a href="backend.PPCgen.html">backend.PPCgen</a>]<br/>
-<a href="backend.Cmconstr.html#addimm">addimm</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#addimm_match">addimm_match</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.PPCgen.html#addimm_1">addimm_1</a> [in <a href="backend.PPCgen.html">backend.PPCgen</a>]<br/>
-<a href="backend.PPCgen.html#addimm_2">addimm_2</a> [in <a href="backend.PPCgen.html">backend.PPCgen</a>]<br/>
-<a href="backend.Cmconstr.html#addressing">addressing</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#addressing_match">addressing_match</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Constprop.html#addr_strength_reduction">addr_strength_reduction</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#addr_strength_reduction_match">addr_strength_reduction_match</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Cminorgen.html#addr_taken_expr">addr_taken_expr</a> [in <a href="backend.Cminorgen.html">backend.Cminorgen</a>]<br/>
-<a href="backend.Cminorgen.html#addr_taken_stmt">addr_taken_stmt</a> [in <a href="backend.Cminorgen.html">backend.Cminorgen</a>]<br/>
-<a href="backend.Allocation.html#add_call">add_call</a> [in <a href="backend.Allocation.html">backend.Allocation</a>]<br/>
-<a href="backend.Allocation.html#add_cond">add_cond</a> [in <a href="backend.Allocation.html">backend.Allocation</a>]<br/>
-<a href="backend.Coloring.html#add_edges_instr">add_edges_instr</a> [in <a href="backend.Coloring.html">backend.Coloring</a>]<br/>
-<a href="backend.Coloring.html#add_edges_instrs">add_edges_instrs</a> [in <a href="backend.Coloring.html">backend.Coloring</a>]<br/>
-<a href="backend.Allocation.html#add_entry">add_entry</a> [in <a href="backend.Allocation.html">backend.Allocation</a>]<br/>
-<a href="backend.Globalenvs.html#add_funct">add_funct</a> [in <a href="backend.Globalenvs.html">backend.Globalenvs</a>]<br/>
-<a href="backend.Globalenvs.html#add_functs">add_functs</a> [in <a href="backend.Globalenvs.html">backend.Globalenvs</a>]<br/>
-<a href="backend.Globalenvs.html#add_globals">add_globals</a> [in <a href="backend.Globalenvs.html">backend.Globalenvs</a>]<br/>
-<a href="backend.RTLgen.html#add_instr">add_instr</a> [in <a href="backend.RTLgen.html">backend.RTLgen</a>]<br/>
-<a href="backend.InterfGraph.html#add_interf">add_interf</a> [in <a href="backend.InterfGraph.html">backend.InterfGraph</a>]<br/>
-<a href="backend.Coloring.html#add_interf_call">add_interf_call</a> [in <a href="backend.Coloring.html">backend.Coloring</a>]<br/>
-<a href="backend.Coloring.html#add_interf_entry">add_interf_entry</a> [in <a href="backend.Coloring.html">backend.Coloring</a>]<br/>
-<a href="backend.Coloring.html#add_interf_live">add_interf_live</a> [in <a href="backend.Coloring.html">backend.Coloring</a>]<br/>
-<a href="backend.Coloring.html#add_interf_move">add_interf_move</a> [in <a href="backend.Coloring.html">backend.Coloring</a>]<br/>
-<a href="backend.InterfGraph.html#add_interf_mreg">add_interf_mreg</a> [in <a href="backend.InterfGraph.html">backend.InterfGraph</a>]<br/>
-<a href="backend.Coloring.html#add_interf_op">add_interf_op</a> [in <a href="backend.Coloring.html">backend.Coloring</a>]<br/>
-<a href="backend.Coloring.html#add_interf_params">add_interf_params</a> [in <a href="backend.Coloring.html">backend.Coloring</a>]<br/>
-<a href="backend.RTLgen.html#add_letvar">add_letvar</a> [in <a href="backend.RTLgen.html">backend.RTLgen</a>]<br/>
-<a href="backend.CSE.html#add_load">add_load</a> [in <a href="backend.CSE.html">backend.CSE</a>]<br/>
-<a href="backend.Allocation.html#add_load">add_load</a> [in <a href="backend.Allocation.html">backend.Allocation</a>]<br/>
-<a href="backend.Cmconstr.html#add_match">add_match</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#add_match_aux">add_match_aux</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.RTLgen.html#add_move">add_move</a> [in <a href="backend.RTLgen.html">backend.RTLgen</a>]<br/>
-<a href="backend.Allocation.html#add_move">add_move</a> [in <a href="backend.Allocation.html">backend.Allocation</a>]<br/>
-<a href="backend.Allocation.html#add_op">add_op</a> [in <a href="backend.Allocation.html">backend.Allocation</a>]<br/>
-<a href="backend.CSE.html#add_op">add_op</a> [in <a href="backend.CSE.html">backend.CSE</a>]<br/>
-<a href="backend.InterfGraph.html#add_pref">add_pref</a> [in <a href="backend.InterfGraph.html">backend.InterfGraph</a>]<br/>
-<a href="backend.Coloring.html#add_prefs_call">add_prefs_call</a> [in <a href="backend.Coloring.html">backend.Coloring</a>]<br/>
-<a href="backend.InterfGraph.html#add_pref_mreg">add_pref_mreg</a> [in <a href="backend.InterfGraph.html">backend.InterfGraph</a>]<br/>
-<a href="backend.Allocation.html#add_reload">add_reload</a> [in <a href="backend.Allocation.html">backend.Allocation</a>]<br/>
-<a href="backend.Allocation.html#add_reloads">add_reloads</a> [in <a href="backend.Allocation.html">backend.Allocation</a>]<br/>
-<a href="backend.Allocation.html#add_return">add_return</a> [in <a href="backend.Allocation.html">backend.Allocation</a>]<br/>
-<a href="backend.CSE.html#add_rhs">add_rhs</a> [in <a href="backend.CSE.html">backend.CSE</a>]<br/>
-<a href="backend.Allocation.html#add_spill">add_spill</a> [in <a href="backend.Allocation.html">backend.Allocation</a>]<br/>
-<a href="backend.Allocation.html#add_store">add_store</a> [in <a href="backend.Allocation.html">backend.Allocation</a>]<br/>
-<a href="backend.Kildall.html#add_successors">add_successors</a> [in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Globalenvs.html#add_symbol">add_symbol</a> [in <a href="backend.Globalenvs.html">backend.Globalenvs</a>]<br/>
-<a href="backend.Kildall.html#add_to_worklist">add_to_worklist</a> [in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Allocation.html#add_undefs">add_undefs</a> [in <a href="backend.Allocation.html">backend.Allocation</a>]<br/>
-<a href="backend.RTLgen.html#add_var">add_var</a> [in <a href="backend.RTLgen.html">backend.RTLgen</a>]<br/>
-<a href="backend.RTLgen.html#add_vars">add_vars</a> [in <a href="backend.RTLgen.html">backend.RTLgen</a>]<br/>
-<a href="backend.Allocproof.html#agree">agree</a> [in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.PPCgenproof1.html#agree">agree</a> [in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="lib.Coqlib.html#align">align</a> [in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="backend.Mach.html#align_16_top">align_16_top</a> [in <a href="backend.Mach.html">backend.Mach</a>]<br/>
-<a href="backend.Mem.html#alloc">alloc</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Coloring.html#alloc_of_coloring">alloc_of_coloring</a> [in <a href="backend.Coloring.html">backend.Coloring</a>]<br/>
-<a href="backend.RTLgen.html#alloc_reg">alloc_reg</a> [in <a href="backend.RTLgen.html">backend.RTLgen</a>]<br/>
-<a href="backend.RTLgen.html#alloc_regs">alloc_regs</a> [in <a href="backend.RTLgen.html">backend.RTLgen</a>]<br/>
-<a href="backend.InterfGraph.html#all_interf_regs">all_interf_regs</a> [in <a href="backend.InterfGraph.html">backend.InterfGraph</a>]<br/>
-<a href="backend.Allocation.html#analyze">analyze</a> [in <a href="backend.Allocation.html">backend.Allocation</a>]<br/>
-<a href="backend.Constprop.html#analyze">analyze</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.CSE.html#analyze">analyze</a> [in <a href="backend.CSE.html">backend.CSE</a>]<br/>
-<a href="lib.Integers.html#and">and</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Cmconstr.html#and">and</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Values.html#and">and</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Cmconstr.html#andimm">andimm</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.PPCgen.html#andimm">andimm</a> [in <a href="backend.PPCgen.html">backend.PPCgen</a>]<br/>
-<a href="lib.Maps.html#append">append</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="backend.Main.html#apply_partial">apply_partial</a> [in <a href="backend.Main.html">backend.Main</a>]<br/>
-<a href="backend.Main.html#apply_total">apply_total</a> [in <a href="backend.Main.html">backend.Main</a>]<br/>
-<a href="backend.Constprop.html#approx_regs">approx_regs</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Cminorgen.html#assign_variable">assign_variable</a> [in <a href="backend.Cminorgen.html">backend.Cminorgen</a>]<br/>
-<a href="backend.Cminorgen.html#assign_variables">assign_variables</a> [in <a href="backend.Cminorgen.html">backend.Cminorgen</a>]<br/>
-<br/><br/><a name="definition_B"></a><h2>B </h2>
-<a href="backend.Parallelmove.html#base_case_Pmov_dec">base_case_Pmov_dec</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Kildall.html#basic_block_list">basic_block_list</a> [in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Kildall.html#basic_block_map">basic_block_map</a> [in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Kildall.html#bbmap">bbmap</a> [in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.RTLgen.html#bind">bind</a> [in <a href="backend.RTLgen.html">backend.RTLgen</a>]<br/>
-<a href="backend.Cminorgen.html#bind">bind</a> [in <a href="backend.Cminorgen.html">backend.Cminorgen</a>]<br/>
-<a href="backend.RTLgen.html#bind2">bind2</a> [in <a href="backend.RTLgen.html">backend.RTLgen</a>]<br/>
-<a href="lib.Inclusion.html#bin_A">bin_A</a> [in <a href="lib.Inclusion.html">lib.Inclusion</a>]<br/>
-<a href="lib.Integers.html#bits_of_Z">bits_of_Z</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#bitwise_binop">bitwise_binop</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Values.html#block">block</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Mem.html#block_agree">block_agree</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#block_contents_agree">block_contents_agree</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#block_contents_extends">block_contents_extends</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="lib.Lattice.html#bot">bot</a> [in <a href="lib.Lattice.html">lib.Lattice</a>]<br/>
-<a href="lib.Lattice.html#bot">bot</a> [in <a href="lib.Lattice.html">lib.Lattice</a>]<br/>
-<a href="backend.Constprop.html#bot">bot</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="lib.Sets.html#bot">bot</a> [in <a href="lib.Sets.html">lib.Sets</a>]<br/>
-<a href="lib.Lattice.html#bot">bot</a> [in <a href="lib.Lattice.html">lib.Lattice</a>]<br/>
-<a href="backend.Tunneling.html#branch_target">branch_target</a> [in <a href="backend.Tunneling.html">backend.Tunneling</a>]<br/>
-<a href="backend.Tunneling.html#branch_target_rec">branch_target_rec</a> [in <a href="backend.Tunneling.html">backend.Tunneling</a>]<br/>
-<a href="backend.Cminorgen.html#build_compilenv">build_compilenv</a> [in <a href="backend.Cminorgen.html">backend.Cminorgen</a>]<br/>
-<br/><br/><a name="definition_C"></a><h2>C </h2>
-<a href="backend.Machabstr2mach.html#callstack">callstack</a> [in <a href="backend.Machabstr2mach.html">backend.Machabstr2mach</a>]<br/>
-<a href="backend.Cminorgenproof.html#callstack">callstack</a> [in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.LTL.html#call_regs">call_regs</a> [in <a href="backend.LTL.html">backend.LTL</a>]<br/>
-<a href="backend.Csharpminor.html#cast">cast</a> [in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="lib.Integers.html#cast16signed">cast16signed</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Values.html#cast16signed">cast16signed</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Cmconstr.html#cast16signed">cast16signed</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#cast16unsigned">cast16unsigned</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Values.html#cast16unsigned">cast16unsigned</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="lib.Integers.html#cast16unsigned">cast16unsigned</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Cmconstr.html#cast8signed">cast8signed</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="lib.Integers.html#cast8signed">cast8signed</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Values.html#cast8signed">cast8signed</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Cmconstr.html#cast8unsigned">cast8unsigned</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Values.html#cast8unsigned">cast8unsigned</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="lib.Integers.html#cast8unsigned">cast8unsigned</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Inclusion.html#check_all_leaves">check_all_leaves</a> [in <a href="lib.Inclusion.html">lib.Inclusion</a>]<br/>
-<a href="backend.Coloring.html#check_coloring">check_coloring</a> [in <a href="backend.Coloring.html">backend.Coloring</a>]<br/>
-<a href="backend.Coloring.html#check_coloring_1">check_coloring_1</a> [in <a href="backend.Coloring.html">backend.Coloring</a>]<br/>
-<a href="backend.Coloring.html#check_coloring_2">check_coloring_2</a> [in <a href="backend.Coloring.html">backend.Coloring</a>]<br/>
-<a href="backend.Coloring.html#check_coloring_3">check_coloring_3</a> [in <a href="backend.Coloring.html">backend.Coloring</a>]<br/>
-<a href="backend.Mem.html#check_cont">check_cont</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="lib.Integers.html#check_equal_on_range">check_equal_on_range</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Mach.html#chunk_of_type">chunk_of_type</a> [in <a href="backend.Mach.html">backend.Mach</a>]<br/>
-<a href="backend.Linearize.html#cleanup_code">cleanup_code</a> [in <a href="backend.Linearize.html">backend.Linearize</a>]<br/>
-<a href="backend.Linearize.html#cleanup_function">cleanup_function</a> [in <a href="backend.Linearize.html">backend.Linearize</a>]<br/>
-<a href="backend.Cmconstr.html#cmp">cmp</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Values.html#cmp">cmp</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="lib.Integers.html#cmp">cmp</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Cmconstr.html#cmpf">cmpf</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Values.html#cmpf">cmpf</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Values.html#cmpu">cmpu</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Cmconstr.html#cmpu">cmpu</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="lib.Integers.html#cmpu">cmpu</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Values.html#cmp_mismatch">cmp_mismatch</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.LTL.html#code">code</a> [in <a href="backend.LTL.html">backend.LTL</a>]<br/>
-<a href="backend.PPC.html#code">code</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.RTL.html#code">code</a> [in <a href="backend.RTL.html">backend.RTL</a>]<br/>
-<a href="backend.Linear.html#code">code</a> [in <a href="backend.Linear.html">backend.Linear</a>]<br/>
-<a href="backend.Mach.html#code">code</a> [in <a href="backend.Mach.html">backend.Mach</a>]<br/>
-<a href="backend.PPCgen.html#code_size">code_size</a> [in <a href="backend.PPCgen.html">backend.PPCgen</a>]<br/>
-<a href="backend.PPCgenproof.html#code_tail">code_tail</a> [in <a href="backend.PPCgenproof.html">backend.PPCgenproof</a>]<br/>
-<a href="lib.Maps.html#combine">combine</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="backend.PPC.html#compare_float">compare_float</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#compare_sint">compare_sint</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#compare_uint">compare_uint</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.Cminorgen.html#compilenv">compilenv</a> [in <a href="backend.Cminorgen.html">backend.Cminorgen</a>]<br/>
-<a href="backend.Cmconstr.html#condexpr_of_expr">condexpr_of_expr</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#conditionalexpr">conditionalexpr</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Constprop.html#cond_strength_reduction">cond_strength_reduction</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#cond_strength_reduction_match">cond_strength_reduction_match</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.RTLtyping.html#consistent">consistent</a> [in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.PPC.html#const_high">const_high</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#const_low">const_low</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.Mem.html#contentmap">contentmap</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#contentmap_agree">contentmap_agree</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#contentmap_inject">contentmap_inject</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Coloringproof.html#correct_alloc_instr">correct_alloc_instr</a> [in <a href="backend.Coloringproof.html">backend.Coloringproof</a>]<br/>
-<a href="backend.Coloringproof.html#correct_interf_instr">correct_interf_instr</a> [in <a href="backend.Coloringproof.html">backend.Coloringproof</a>]<br/>
-<a href="backend.PPCgen.html#crbit_for_cond">crbit_for_cond</a> [in <a href="backend.PPCgen.html">backend.PPCgen</a>]<br/>
-<a href="backend.PPCgen.html#crbit_for_fcmp">crbit_for_fcmp</a> [in <a href="backend.PPCgen.html">backend.PPCgen</a>]<br/>
-<a href="backend.PPCgen.html#crbit_for_icmp">crbit_for_icmp</a> [in <a href="backend.PPCgen.html">backend.PPCgen</a>]<br/>
-<br/><br/><a name="definition_D"></a><h2>D </h2>
-<a href="backend.RTLtyping.html#decode">decode</a> [in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.Parallelmove.html#def">def</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.RTLtyping.html#definite">definite</a> [in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.Conventions.html#destroyed_at_call">destroyed_at_call</a> [in <a href="backend.Conventions.html">backend.Conventions</a>]<br/>
-<a href="backend.Conventions.html#destroyed_at_call_regs">destroyed_at_call_regs</a> [in <a href="backend.Conventions.html">backend.Conventions</a>]<br/>
-<a href="backend.Locations.html#diff">diff</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Parallelmove.html#diff_dec">diff_dec</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Locations.html#disjoint">disjoint</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Values.html#divf">divf</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Cmconstr.html#divf">divf</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#divs">divs</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="lib.Integers.html#divs">divs</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Values.html#divs">divs</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Cmconstr.html#divu">divu</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Values.html#divu">divu</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="lib.Integers.html#divu">divu</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Cmconstr.html#divu_match">divu_match</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Allocproof_aux.html#Done_well_formed">Done_well_formed</a> [in <a href="backend.Allocproof_aux.html">backend.Allocproof_aux</a>]<br/>
-<a href="backend.Conventions.html#drop1">drop1</a> [in <a href="backend.Conventions.html">backend.Conventions</a>]<br/>
-<a href="backend.Conventions.html#drop2">drop2</a> [in <a href="backend.Conventions.html">backend.Conventions</a>]<br/>
-<br/><br/><a name="definition_E"></a><h2>E </h2>
-<a href="lib.Sets.html#elements">elements</a> [in <a href="lib.Sets.html">lib.Sets</a>]<br/>
-<a href="lib.Maps.html#elements">elements</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#elt">elt</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="backend.RTLtyping.html#elt">elt</a> [in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="lib.Sets.html#elt">elt</a> [in <a href="lib.Sets.html">lib.Sets</a>]<br/>
-<a href="lib.union_find.html#elt">elt</a> [in <a href="lib.union_find.html">lib.union_find</a>]<br/>
-<a href="lib.union_find.html#elt">elt</a> [in <a href="lib.union_find.html">lib.union_find</a>]<br/>
-<a href="lib.union_find.html#elt">elt</a> [in <a href="lib.union_find.html">lib.union_find</a>]<br/>
-<a href="lib.Maps.html#elt">elt</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#elt">elt</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#elt">elt</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#elt_eq">elt_eq</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#elt_eq">elt_eq</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#elt_eq">elt_eq</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#elt_eq">elt_eq</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Sets.html#empty">empty</a> [in <a href="lib.Sets.html">lib.Sets</a>]<br/>
-<a href="lib.Maps.html#empty">empty</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.union_find.html#empty">empty</a> [in <a href="lib.union_find.html">lib.union_find</a>]<br/>
-<a href="backend.RTLtyping.html#empty">empty</a> [in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.Globalenvs.html#empty">empty</a> [in <a href="backend.Globalenvs.html">backend.Globalenvs</a>]<br/>
-<a href="backend.Mem.html#empty">empty</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#empty_block">empty_block</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Csharpminor.html#empty_env">empty_env</a> [in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Machabstr.html#empty_frame">empty_frame</a> [in <a href="backend.Machabstr.html">backend.Machabstr</a>]<br/>
-<a href="backend.InterfGraph.html#empty_graph">empty_graph</a> [in <a href="backend.InterfGraph.html">backend.InterfGraph</a>]<br/>
-<a href="backend.CSE.html#empty_numbering">empty_numbering</a> [in <a href="backend.CSE.html">backend.CSE</a>]<br/>
-<a href="backend.RTLtyping.html#encode">encode</a> [in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.Linearize.html#enumerate">enumerate</a> [in <a href="backend.Linearize.html">backend.Linearize</a>]<br/>
-<a href="backend.Csharpminor.html#env">env</a> [in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Parallelmove.html#Env">Env</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Cminor.html#env">env</a> [in <a href="backend.Cminor.html">backend.Cminor</a>]<br/>
-<a href="backend.Mach.html#eq">eq</a> [in <a href="backend.Mach.html">backend.Mach</a>]<br/>
-<a href="lib.Ordered.html#eq">eq</a> [in <a href="lib.Ordered.html">lib.Ordered</a>]<br/>
-<a href="backend.RTLtyping.html#eq">eq</a> [in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.CSEproof.html#eq">eq</a> [in <a href="backend.CSEproof.html">backend.CSEproof</a>]<br/>
-<a href="lib.Maps.html#eq">eq</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="backend.Locations.html#eq">eq</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="lib.Ordered.html#eq">eq</a> [in <a href="lib.Ordered.html">lib.Ordered</a>]<br/>
-<a href="backend.Registers.html#eq">eq</a> [in <a href="backend.Registers.html">backend.Registers</a>]<br/>
-<a href="lib.Ordered.html#eq">eq</a> [in <a href="lib.Ordered.html">lib.Ordered</a>]<br/>
-<a href="backend.PPC.html#eq">eq</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="lib.Integers.html#eq">eq</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#eqm">eqm</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#eqmod">eqmod</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.CSE.html#equation_holds">equation_holds</a> [in <a href="backend.CSE.html">backend.CSE</a>]<br/>
-<a href="backend.Values.html#eq_block">eq_block</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.CSE.html#eq_list_valnum">eq_list_valnum</a> [in <a href="backend.CSE.html">backend.CSE</a>]<br/>
-<a href="backend.CSE.html#eq_rhs">eq_rhs</a> [in <a href="backend.CSE.html">backend.CSE</a>]<br/>
-<a href="backend.CSE.html#eq_valnum">eq_valnum</a> [in <a href="backend.CSE.html">backend.CSE</a>]<br/>
-<a href="backend.RTLtyping.html#error">error</a> [in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.RTLgen.html#error">error</a> [in <a href="backend.RTLgen.html">backend.RTLgen</a>]<br/>
-<a href="backend.Op.html#eval_addressing">eval_addressing</a> [in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Op.html#eval_addressing_total">eval_addressing_total</a> [in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Op.html#eval_compare_null">eval_compare_null</a> [in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Csharpminor.html#eval_compare_null">eval_compare_null</a> [in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Op.html#eval_condition">eval_condition</a> [in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Op.html#eval_condition_total">eval_condition_total</a> [in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Cminorgenproof.html#eval_exprlist_prop">eval_exprlist_prop</a> [in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#eval_expr_prop">eval_expr_prop</a> [in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#eval_funcall_prop">eval_funcall_prop</a> [in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Op.html#eval_operation">eval_operation</a> [in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Csharpminor.html#eval_operation">eval_operation</a> [in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Op.html#eval_operation_total">eval_operation_total</a> [in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Constprop.html#eval_static_condition">eval_static_condition</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_condition_match">eval_static_condition_match</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_operation">eval_static_operation</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#eval_static_operation_match">eval_static_operation_match</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Parallelmove.html#exec">exec</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Linearizeproof.html#exec_blocks_prop">exec_blocks_prop</a> [in <a href="backend.Linearizeproof.html">backend.Linearizeproof</a>]<br/>
-<a href="backend.Tunnelingproof.html#exec_blocks_prop">exec_blocks_prop</a> [in <a href="backend.Tunnelingproof.html">backend.Tunnelingproof</a>]<br/>
-<a href="backend.Linearizeproof.html#exec_block_prop">exec_block_prop</a> [in <a href="backend.Linearizeproof.html">backend.Linearizeproof</a>]<br/>
-<a href="backend.Tunnelingproof.html#exec_block_prop">exec_block_prop</a> [in <a href="backend.Tunnelingproof.html">backend.Tunnelingproof</a>]<br/>
-<a href="backend.Machabstr2mach.html#exec_function_body_prop">exec_function_body_prop</a> [in <a href="backend.Machabstr2mach.html">backend.Machabstr2mach</a>]<br/>
-<a href="backend.PPCgenproof.html#exec_function_body_prop">exec_function_body_prop</a> [in <a href="backend.PPCgenproof.html">backend.PPCgenproof</a>]<br/>
-<a href="backend.Machtyping.html#exec_function_body_prop">exec_function_body_prop</a> [in <a href="backend.Machtyping.html">backend.Machtyping</a>]<br/>
-<a href="backend.Stackingproof.html#exec_function_prop">exec_function_prop</a> [in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="backend.Machtyping.html#exec_function_prop">exec_function_prop</a> [in <a href="backend.Machtyping.html">backend.Machtyping</a>]<br/>
-<a href="backend.PPCgenproof.html#exec_function_prop">exec_function_prop</a> [in <a href="backend.PPCgenproof.html">backend.PPCgenproof</a>]<br/>
-<a href="backend.Constpropproof.html#exec_function_prop">exec_function_prop</a> [in <a href="backend.Constpropproof.html">backend.Constpropproof</a>]<br/>
-<a href="backend.Linearizeproof.html#exec_function_prop">exec_function_prop</a> [in <a href="backend.Linearizeproof.html">backend.Linearizeproof</a>]<br/>
-<a href="backend.Machabstr2mach.html#exec_function_prop">exec_function_prop</a> [in <a href="backend.Machabstr2mach.html">backend.Machabstr2mach</a>]<br/>
-<a href="backend.CSEproof.html#exec_function_prop">exec_function_prop</a> [in <a href="backend.CSEproof.html">backend.CSEproof</a>]<br/>
-<a href="backend.Tunnelingproof.html#exec_function_prop">exec_function_prop</a> [in <a href="backend.Tunnelingproof.html">backend.Tunnelingproof</a>]<br/>
-<a href="backend.Allocproof.html#exec_function_prop">exec_function_prop</a> [in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.RTLtyping.html#exec_function_subject_reduction">exec_function_subject_reduction</a> [in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.PPC.html#exec_instr">exec_instr</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.Allocproof.html#exec_instrs_prop">exec_instrs_prop</a> [in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.Tunnelingproof.html#exec_instrs_prop">exec_instrs_prop</a> [in <a href="backend.Tunnelingproof.html">backend.Tunnelingproof</a>]<br/>
-<a href="backend.Machabstr2mach.html#exec_instrs_prop">exec_instrs_prop</a> [in <a href="backend.Machabstr2mach.html">backend.Machabstr2mach</a>]<br/>
-<a href="backend.CSEproof.html#exec_instrs_prop">exec_instrs_prop</a> [in <a href="backend.CSEproof.html">backend.CSEproof</a>]<br/>
-<a href="backend.Constpropproof.html#exec_instrs_prop">exec_instrs_prop</a> [in <a href="backend.Constpropproof.html">backend.Constpropproof</a>]<br/>
-<a href="backend.Linearizeproof.html#exec_instrs_prop">exec_instrs_prop</a> [in <a href="backend.Linearizeproof.html">backend.Linearizeproof</a>]<br/>
-<a href="backend.Allocproof.html#exec_instr_prop">exec_instr_prop</a> [in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.Machabstr2mach.html#exec_instr_prop">exec_instr_prop</a> [in <a href="backend.Machabstr2mach.html">backend.Machabstr2mach</a>]<br/>
-<a href="backend.Machtyping.html#exec_instr_prop">exec_instr_prop</a> [in <a href="backend.Machtyping.html">backend.Machtyping</a>]<br/>
-<a href="backend.Constpropproof.html#exec_instr_prop">exec_instr_prop</a> [in <a href="backend.Constpropproof.html">backend.Constpropproof</a>]<br/>
-<a href="backend.CSEproof.html#exec_instr_prop">exec_instr_prop</a> [in <a href="backend.CSEproof.html">backend.CSEproof</a>]<br/>
-<a href="backend.Tunnelingproof.html#exec_instr_prop">exec_instr_prop</a> [in <a href="backend.Tunnelingproof.html">backend.Tunnelingproof</a>]<br/>
-<a href="backend.Stackingproof.html#exec_instr_prop">exec_instr_prop</a> [in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="backend.Linearizeproof.html#exec_instr_prop">exec_instr_prop</a> [in <a href="backend.Linearizeproof.html">backend.Linearizeproof</a>]<br/>
-<a href="backend.PPCgenproof.html#exec_instr_prop">exec_instr_prop</a> [in <a href="backend.PPCgenproof.html">backend.PPCgenproof</a>]<br/>
-<a href="backend.RTLtyping.html#exec_instr_subject_reduction">exec_instr_subject_reduction</a> [in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.Csharpminor.html#exec_program">exec_program</a> [in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.LTL.html#exec_program">exec_program</a> [in <a href="backend.LTL.html">backend.LTL</a>]<br/>
-<a href="backend.Cminor.html#exec_program">exec_program</a> [in <a href="backend.Cminor.html">backend.Cminor</a>]<br/>
-<a href="backend.RTL.html#exec_program">exec_program</a> [in <a href="backend.RTL.html">backend.RTL</a>]<br/>
-<a href="backend.Mach.html#exec_program">exec_program</a> [in <a href="backend.Mach.html">backend.Mach</a>]<br/>
-<a href="backend.Machabstr.html#exec_program">exec_program</a> [in <a href="backend.Machabstr.html">backend.Machabstr</a>]<br/>
-<a href="backend.Linear.html#exec_program">exec_program</a> [in <a href="backend.Linear.html">backend.Linear</a>]<br/>
-<a href="backend.PPC.html#exec_program">exec_program</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.Cminorgenproof.html#exec_stmtlist_prop">exec_stmtlist_prop</a> [in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#exec_stmt_prop">exec_stmt_prop</a> [in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Mem.html#extends">extends</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#extend_inject">extend_inject</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<br/><br/><a name="definition_F"></a><h2>F </h2>
-<a href="backend.Globalenvs.html#find_funct">find_funct</a> [in <a href="backend.Globalenvs.html">backend.Globalenvs</a>]<br/>
-<a href="backend.LTL.html#find_function">find_function</a> [in <a href="backend.LTL.html">backend.LTL</a>]<br/>
-<a href="backend.Mach.html#find_function">find_function</a> [in <a href="backend.Mach.html">backend.Mach</a>]<br/>
-<a href="backend.RTL.html#find_function">find_function</a> [in <a href="backend.RTL.html">backend.RTL</a>]<br/>
-<a href="backend.Linear.html#find_function">find_function</a> [in <a href="backend.Linear.html">backend.Linear</a>]<br/>
-<a href="backend.Allocproof.html#find_function2">find_function2</a> [in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.Globalenvs.html#find_funct_ptr">find_funct_ptr</a> [in <a href="backend.Globalenvs.html">backend.Globalenvs</a>]<br/>
-<a href="backend.PPC.html#find_instr">find_instr</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.Mach.html#find_label">find_label</a> [in <a href="backend.Mach.html">backend.Mach</a>]<br/>
-<a href="backend.PPCgenproof.html#find_label">find_label</a> [in <a href="backend.PPCgenproof.html">backend.PPCgenproof</a>]<br/>
-<a href="backend.Linear.html#find_label">find_label</a> [in <a href="backend.Linear.html">backend.Linear</a>]<br/>
-<a href="backend.RTLgen.html#find_letvar">find_letvar</a> [in <a href="backend.RTLgen.html">backend.RTLgen</a>]<br/>
-<a href="backend.CSE.html#find_load">find_load</a> [in <a href="backend.CSE.html">backend.CSE</a>]<br/>
-<a href="backend.CSE.html#find_op">find_op</a> [in <a href="backend.CSE.html">backend.CSE</a>]<br/>
-<a href="backend.CSE.html#find_rhs">find_rhs</a> [in <a href="backend.CSE.html">backend.CSE</a>]<br/>
-<a href="backend.Globalenvs.html#find_symbol">find_symbol</a> [in <a href="backend.Globalenvs.html">backend.Globalenvs</a>]<br/>
-<a href="backend.Op.html#find_symbol_offset">find_symbol_offset</a> [in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.CSE.html#find_valnum_rhs">find_valnum_rhs</a> [in <a href="backend.CSE.html">backend.CSE</a>]<br/>
-<a href="backend.RTLgen.html#find_var">find_var</a> [in <a href="backend.RTLgen.html">backend.RTLgen</a>]<br/>
-<a href="backend.Kildall.html#fixpoint">fixpoint</a> [in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Kildall.html#fixpoint">fixpoint</a> [in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Kildall.html#fixpoint">fixpoint</a> [in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="lib.Inclusion.html#flatten">flatten</a> [in <a href="lib.Inclusion.html">lib.Inclusion</a>]<br/>
-<a href="lib.Inclusion.html#flatten_aux">flatten_aux</a> [in <a href="lib.Inclusion.html">lib.Inclusion</a>]<br/>
-<a href="backend.PPCgen.html#floatcomp">floatcomp</a> [in <a href="backend.PPCgen.html">backend.PPCgen</a>]<br/>
-<a href="backend.Values.html#floatofint">floatofint</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Cmconstr.html#floatofint">floatofint</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#floatofintu">floatofintu</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Values.html#floatofintu">floatofintu</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Lineartyping.html#float_callee_save">float_callee_save</a> [in <a href="backend.Lineartyping.html">backend.Lineartyping</a>]<br/>
-<a href="backend.Conventions.html#float_callee_save_regs">float_callee_save_regs</a> [in <a href="backend.Conventions.html">backend.Conventions</a>]<br/>
-<a href="backend.Lineartyping.html#float_local">float_local</a> [in <a href="backend.Lineartyping.html">backend.Lineartyping</a>]<br/>
-<a href="backend.Conventions.html#float_param_regs">float_param_regs</a> [in <a href="backend.Conventions.html">backend.Conventions</a>]<br/>
-<a href="backend.Csharpminor.html#fn_params_names">fn_params_names</a> [in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Csharpminor.html#fn_variables">fn_variables</a> [in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Csharpminor.html#fn_vars_names">fn_vars_names</a> [in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="lib.Sets.html#fold">fold</a> [in <a href="lib.Sets.html">lib.Sets</a>]<br/>
-<a href="lib.Maps.html#fold">fold</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="backend.RTLtyping.html#fold2">fold2</a> [in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="lib.Sets.html#for_all">for_all</a> [in <a href="lib.Sets.html">lib.Sets</a>]<br/>
-<a href="backend.Machabstr.html#frame">frame</a> [in <a href="backend.Machabstr.html">backend.Machabstr</a>]<br/>
-<a href="backend.Mem.html#free">free</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#free_list">free_list</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.PPCgen.html#freg_of">freg_of</a> [in <a href="backend.PPCgen.html">backend.PPCgen</a>]<br/>
-<a href="backend.Lineartyping.html#function_bounds">function_bounds</a> [in <a href="backend.Lineartyping.html">backend.Lineartyping</a>]<br/>
-<br/><br/><a name="definition_G"></a><h2>G </h2>
-<a href="lib.Lattice.html#ge">ge</a> [in <a href="lib.Lattice.html">lib.Lattice</a>]<br/>
-<a href="backend.CSE.html#ge">ge</a> [in <a href="backend.CSE.html">backend.CSE</a>]<br/>
-<a href="lib.Lattice.html#ge">ge</a> [in <a href="lib.Lattice.html">lib.Lattice</a>]<br/>
-<a href="backend.Constprop.html#ge">ge</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="lib.Lattice.html#ge">ge</a> [in <a href="lib.Lattice.html">lib.Lattice</a>]<br/>
-<a href="lib.Sets.html#ge">ge</a> [in <a href="lib.Sets.html">lib.Sets</a>]<br/>
-<a href="backend.Cminor.html#genv">genv</a> [in <a href="backend.Cminor.html">backend.Cminor</a>]<br/>
-<a href="backend.LTL.html#genv">genv</a> [in <a href="backend.LTL.html">backend.LTL</a>]<br/>
-<a href="backend.PPC.html#genv">genv</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.Csharpminor.html#genv">genv</a> [in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.RTL.html#genv">genv</a> [in <a href="backend.RTL.html">backend.RTL</a>]<br/>
-<a href="backend.Mach.html#genv">genv</a> [in <a href="backend.Mach.html">backend.Mach</a>]<br/>
-<a href="backend.Linear.html#genv">genv</a> [in <a href="backend.Linear.html">backend.Linear</a>]<br/>
-<a href="lib.Maps.html#get">get</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#get">get</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#get">get</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="backend.Parallelmove.html#Get">Get</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Locations.html#get">get</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="lib.Lattice.html#get">get</a> [in <a href="lib.Lattice.html">lib.Lattice</a>]<br/>
-<a href="lib.Maps.html#get">get</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="backend.Parallelmove.html#get">get</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.RTLtyping.html#get">get</a> [in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.Parallelmove.html#getdst">getdst</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Mem.html#getN">getN</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Parallelmove.html#getsrc">getsrc</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Globalenvs.html#globalenv">globalenv</a> [in <a href="backend.Globalenvs.html">backend.Globalenvs</a>]<br/>
-<a href="backend.Globalenvs.html#globalenv_initmem">globalenv_initmem</a> [in <a href="backend.Globalenvs.html">backend.Globalenvs</a>]<br/>
-<a href="backend.Kildall.html#good_state">good_state</a> [in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.PPC.html#goto_label">goto_label</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#gpr_or_zero">gpr_or_zero</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.InterfGraph.html#graph_incl">graph_incl</a> [in <a href="backend.InterfGraph.html">backend.InterfGraph</a>]<br/>
-<br/><br/><a name="definition_H"></a><h2>H </h2>
-<a href="lib.Integers.html#half_modulus">half_modulus</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Values.html#has_type">has_type</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Values.html#has_type_list">has_type_list</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Parallelmove.html#head_but_last">head_but_last</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Mem.html#high_bound">high_bound</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.PPCgen.html#high_s">high_s</a> [in <a href="backend.PPCgen.html">backend.PPCgen</a>]<br/>
-<a href="backend.PPCgen.html#high_u">high_u</a> [in <a href="backend.PPCgen.html">backend.PPCgen</a>]<br/>
-<br/><br/><a name="definition_I"></a><h2>I </h2>
-<a href="backend.AST.html#ident">ident</a> [in <a href="backend.AST.html">backend.AST</a>]<br/>
-<a href="lib.union_find.html#identify">identify</a> [in <a href="lib.union_find.html">lib.union_find</a>]<br/>
-<a href="lib.union_find.html#identify_base">identify_base</a> [in <a href="lib.union_find.html">lib.union_find</a>]<br/>
-<a href="backend.AST.html#ident_eq">ident_eq</a> [in <a href="backend.AST.html">backend.AST</a>]<br/>
-<a href="backend.Cmconstr.html#ifthenelse">ifthenelse</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.RTLtyping.html#included">included</a> [in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.Locations.html#index">index</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="lib.Maps.html#index">index</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#index">index</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="backend.Stackingproof.html#index_diff">index_diff</a> [in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="backend.Conventions.html#index_float_callee_save">index_float_callee_save</a> [in <a href="backend.Conventions.html">backend.Conventions</a>]<br/>
-<a href="backend.Conventions.html#index_int_callee_save">index_int_callee_save</a> [in <a href="backend.Conventions.html">backend.Conventions</a>]<br/>
-<a href="backend.Stackingproof.html#index_val">index_val</a> [in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="backend.Stackingproof.html#index_valid">index_valid</a> [in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="lib.Maps.html#init">init</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="backend.Locations.html#init">init</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="lib.Maps.html#init">init</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#init">init</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="backend.Machabstr.html#init_frame">init_frame</a> [in <a href="backend.Machabstr.html">backend.Machabstr</a>]<br/>
-<a href="backend.RTLgen.html#init_mapping">init_mapping</a> [in <a href="backend.RTLgen.html">backend.RTLgen</a>]<br/>
-<a href="backend.Globalenvs.html#init_mem">init_mem</a> [in <a href="backend.Globalenvs.html">backend.Globalenvs</a>]<br/>
-<a href="backend.RTL.html#init_regs">init_regs</a> [in <a href="backend.RTL.html">backend.RTL</a>]<br/>
-<a href="backend.RTLgen.html#init_state">init_state</a> [in <a href="backend.RTLgen.html">backend.RTLgen</a>]<br/>
-<a href="backend.Mem.html#inject_incr">inject_incr</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="lib.Inclusion.html#insert_bin">insert_bin</a> [in <a href="lib.Inclusion.html">lib.Inclusion</a>]<br/>
-<a href="backend.InterfGraph.html#interfere">interfere</a> [in <a href="backend.InterfGraph.html">backend.InterfGraph</a>]<br/>
-<a href="backend.InterfGraph.html#interfere_mreg">interfere_mreg</a> [in <a href="backend.InterfGraph.html">backend.InterfGraph</a>]<br/>
-<a href="backend.Coloring.html#interf_graph">interf_graph</a> [in <a href="backend.Coloring.html">backend.Coloring</a>]<br/>
-<a href="backend.Cmconstr.html#intoffloat">intoffloat</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Values.html#intoffloat">intoffloat</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Constprop.html#intval">intval</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Lineartyping.html#int_callee_save">int_callee_save</a> [in <a href="backend.Lineartyping.html">backend.Lineartyping</a>]<br/>
-<a href="backend.Conventions.html#int_callee_save_regs">int_callee_save_regs</a> [in <a href="backend.Conventions.html">backend.Conventions</a>]<br/>
-<a href="backend.Lineartyping.html#int_local">int_local</a> [in <a href="backend.Lineartyping.html">backend.Lineartyping</a>]<br/>
-<a href="lib.Integers.html#int_of_one_bits">int_of_one_bits</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Conventions.html#int_param_regs">int_param_regs</a> [in <a href="backend.Conventions.html">backend.Conventions</a>]<br/>
-<a href="backend.Mem.html#in_bounds">in_bounds</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Kildall.html#in_incr">in_incr</a> [in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="lib.Integers.html#in_range">in_range</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.PPCgen.html#ireg_of">ireg_of</a> [in <a href="backend.PPCgen.html">backend.PPCgen</a>]<br/>
-<a href="backend.Kildall.html#is_basic_block_head">is_basic_block_head</a> [in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Values.html#is_bool">is_bool</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.PPCgenproof1.html#is_data_reg">is_data_reg</a> [in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="lib.Integers.html#is_false">is_false</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Values.html#is_false">is_false</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Tunneling.html#is_goto_block">is_goto_block</a> [in <a href="backend.Tunneling.html">backend.Tunneling</a>]<br/>
-<a href="backend.PPC.html#is_label">is_label</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.Mach.html#is_label">is_label</a> [in <a href="backend.Mach.html">backend.Mach</a>]<br/>
-<a href="backend.Linear.html#is_label">is_label</a> [in <a href="backend.Linear.html">backend.Linear</a>]<br/>
-<a href="backend.Op.html#is_move_operation">is_move_operation</a> [in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="lib.Integers.html#is_power2">is_power2</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#is_rlw_mask">is_rlw_mask</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#is_rlw_mask_rec">is_rlw_mask_rec</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.CSE.html#is_trivial_op">is_trivial_op</a> [in <a href="backend.CSE.html">backend.CSE</a>]<br/>
-<a href="lib.Integers.html#is_true">is_true</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Values.html#is_true">is_true</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Kildall.html#iterate">iterate</a> [in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Kildall.html#iter_step">iter_step</a> [in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<br/><br/><a name="definition_K"></a><h2>K </h2>
-<a href="backend.CSE.html#kill_loads">kill_loads</a> [in <a href="backend.CSE.html">backend.CSE</a>]<br/>
-<a href="backend.CSE.html#kill_load_eqs">kill_load_eqs</a> [in <a href="backend.CSE.html">backend.CSE</a>]<br/>
-<br/><br/><a name="definition_L"></a><h2>L </h2>
-<a href="backend.Linear.html#label">label</a> [in <a href="backend.Linear.html">backend.Linear</a>]<br/>
-<a href="backend.PPC.html#label">label</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.Mach.html#label">label</a> [in <a href="backend.Mach.html">backend.Mach</a>]<br/>
-<a href="backend.PPC.html#label_pos">label_pos</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.Parallelmove.html#last">last</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Linearize.html#lbl">lbl</a> [in <a href="backend.Linearize.html">backend.Linearize</a>]<br/>
-<a href="backend.Linearize.html#lbl">lbl</a> [in <a href="backend.Linearize.html">backend.Linearize</a>]<br/>
-<a href="lib.Inclusion.html#leaf">leaf</a> [in <a href="lib.Inclusion.html">lib.Inclusion</a>]<br/>
-<a href="lib.Inclusion.html#leaf">leaf</a> [in <a href="lib.Inclusion.html">lib.Inclusion</a>]<br/>
-<a href="lib.Inclusion.html#leaf">leaf</a> [in <a href="lib.Inclusion.html">lib.Inclusion</a>]<br/>
-<a href="backend.Cminor.html#letenv">letenv</a> [in <a href="backend.Cminor.html">backend.Cminor</a>]<br/>
-<a href="backend.Csharpminor.html#letenv">letenv</a> [in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Cmconstr.html#lift">lift</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#lift_condexpr">lift_condexpr</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#lift_expr">lift_expr</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#lift_exprlist">lift_exprlist</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Linearize.html#linearize_block">linearize_block</a> [in <a href="backend.Linearize.html">backend.Linearize</a>]<br/>
-<a href="backend.Linearize.html#linearize_body">linearize_body</a> [in <a href="backend.Linearize.html">backend.Linearize</a>]<br/>
-<a href="backend.Linearize.html#linearize_function">linearize_function</a> [in <a href="backend.Linearize.html">backend.Linearize</a>]<br/>
-<a href="backend.Machtyping.html#link_invariant">link_invariant</a> [in <a href="backend.Machtyping.html">backend.Machtyping</a>]<br/>
-<a href="backend.Parallelmove.html#listsLoc2Moves">listsLoc2Moves</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Allocation.html#listsLoc2Moves">listsLoc2Moves</a> [in <a href="backend.Allocation.html">backend.Allocation</a>]<br/>
-<a href="lib.Coqlib.html#list_disjoint">list_disjoint</a> [in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="backend.Allocproof.html#live0">live0</a> [in <a href="backend.Allocproof.html">backend.Allocproof</a>]<br/>
-<a href="backend.Mem.html#load">load</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Cmconstr.html#load">load</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.PPCgen.html#loadimm">loadimm</a> [in <a href="backend.PPCgen.html">backend.PPCgen</a>]<br/>
-<a href="backend.PPCgen.html#loadind">loadind</a> [in <a href="backend.PPCgen.html">backend.PPCgen</a>]<br/>
-<a href="backend.PPCgen.html#loadind_aux">loadind_aux</a> [in <a href="backend.PPCgen.html">backend.PPCgen</a>]<br/>
-<a href="backend.Mem.html#loadv">loadv</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.PPC.html#load1">load1</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#load2">load2</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.Mem.html#load_contents">load_contents</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Values.html#load_result">load_result</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Mach.html#load_stack">load_stack</a> [in <a href="backend.Mach.html">backend.Mach</a>]<br/>
-<a href="backend.LTL.html#locset">locset</a> [in <a href="backend.LTL.html">backend.LTL</a>]<br/>
-<a href="backend.Linear.html#locset">locset</a> [in <a href="backend.Linear.html">backend.Linear</a>]<br/>
-<a href="backend.Conventions.html#locs_acceptable">locs_acceptable</a> [in <a href="backend.Conventions.html">backend.Conventions</a>]<br/>
-<a href="backend.Alloctyping.html#locs_read_ok">locs_read_ok</a> [in <a href="backend.Alloctyping.html">backend.Alloctyping</a>]<br/>
-<a href="backend.Alloctyping.html#locs_write_ok">locs_write_ok</a> [in <a href="backend.Alloctyping.html">backend.Alloctyping</a>]<br/>
-<a href="backend.Conventions.html#loc_acceptable">loc_acceptable</a> [in <a href="backend.Conventions.html">backend.Conventions</a>]<br/>
-<a href="backend.Conventions.html#loc_arguments">loc_arguments</a> [in <a href="backend.Conventions.html">backend.Conventions</a>]<br/>
-<a href="backend.Conventions.html#loc_arguments_rec">loc_arguments_rec</a> [in <a href="backend.Conventions.html">backend.Conventions</a>]<br/>
-<a href="backend.Conventions.html#loc_argument_acceptable">loc_argument_acceptable</a> [in <a href="backend.Conventions.html">backend.Conventions</a>]<br/>
-<a href="backend.Coloring.html#loc_is_acceptable">loc_is_acceptable</a> [in <a href="backend.Coloring.html">backend.Coloring</a>]<br/>
-<a href="backend.Conventions.html#loc_parameters">loc_parameters</a> [in <a href="backend.Conventions.html">backend.Conventions</a>]<br/>
-<a href="backend.Alloctyping.html#loc_read_ok">loc_read_ok</a> [in <a href="backend.Alloctyping.html">backend.Alloctyping</a>]<br/>
-<a href="backend.Conventions.html#loc_result">loc_result</a> [in <a href="backend.Conventions.html">backend.Conventions</a>]<br/>
-<a href="backend.Alloctyping.html#loc_write_ok">loc_write_ok</a> [in <a href="backend.Alloctyping.html">backend.Alloctyping</a>]<br/>
-<a href="backend.Mem.html#low_bound">low_bound</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.PPCgen.html#low_s">low_s</a> [in <a href="backend.PPCgen.html">backend.PPCgen</a>]<br/>
-<a href="backend.PPCgen.html#low_u">low_u</a> [in <a href="backend.PPCgen.html">backend.PPCgen</a>]<br/>
-<a href="lib.Integers.html#lt">lt</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Ordered.html#lt">lt</a> [in <a href="lib.Ordered.html">lib.Ordered</a>]<br/>
-<a href="lib.Ordered.html#lt">lt</a> [in <a href="lib.Ordered.html">lib.Ordered</a>]<br/>
-<a href="lib.Ordered.html#lt">lt</a> [in <a href="lib.Ordered.html">lib.Ordered</a>]<br/>
-<a href="lib.Integers.html#ltu">ltu</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Lattice.html#lub">lub</a> [in <a href="lib.Lattice.html">lib.Lattice</a>]<br/>
-<a href="lib.Lattice.html#lub">lub</a> [in <a href="lib.Lattice.html">lib.Lattice</a>]<br/>
-<a href="lib.Sets.html#lub">lub</a> [in <a href="lib.Sets.html">lib.Sets</a>]<br/>
-<a href="lib.Lattice.html#lub">lub</a> [in <a href="lib.Lattice.html">lib.Lattice</a>]<br/>
-<a href="backend.Constprop.html#lub">lub</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<br/><br/><a name="definition_M"></a><h2>M </h2>
-<a href="backend.Constprop.html#make_addimm">make_addimm</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#make_andimm">make_andimm</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Cminorgen.html#make_cast">make_cast</a> [in <a href="backend.Cminorgen.html">backend.Cminorgen</a>]<br/>
-<a href="backend.Stacking.html#make_env">make_env</a> [in <a href="backend.Stacking.html">backend.Stacking</a>]<br/>
-<a href="backend.Cminorgen.html#make_load">make_load</a> [in <a href="backend.Cminorgen.html">backend.Cminorgen</a>]<br/>
-<a href="backend.Constprop.html#make_mulimm">make_mulimm</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Cminorgen.html#make_op">make_op</a> [in <a href="backend.Cminorgen.html">backend.Cminorgen</a>]<br/>
-<a href="backend.Constprop.html#make_orimm">make_orimm</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Kildall.html#make_predecessors">make_predecessors</a> [in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Constprop.html#make_shlimm">make_shlimm</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#make_shrimm">make_shrimm</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#make_shruimm">make_shruimm</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Cminorgen.html#make_stackaddr">make_stackaddr</a> [in <a href="backend.Cminorgen.html">backend.Cminorgen</a>]<br/>
-<a href="backend.Cminorgen.html#make_store">make_store</a> [in <a href="backend.Cminorgen.html">backend.Cminorgen</a>]<br/>
-<a href="backend.Constprop.html#make_xorimm">make_xorimm</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="lib.Maps.html#map">map</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#map">map</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#map">map</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#map">map</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="backend.RTLtyping.html#mapped">mapped</a> [in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.RTLgenproof.html#match_return_outcome">match_return_outcome</a> [in <a href="backend.RTLgenproof.html">backend.RTLgenproof</a>]<br/>
-<a href="backend.RTLgenproof.html#match_return_reg">match_return_reg</a> [in <a href="backend.RTLgenproof.html">backend.RTLgenproof</a>]<br/>
-<a href="backend.Lineartyping.html#max_over_instrs">max_over_instrs</a> [in <a href="backend.Lineartyping.html">backend.Lineartyping</a>]<br/>
-<a href="backend.Lineartyping.html#max_over_list">max_over_list</a> [in <a href="backend.Lineartyping.html">backend.Lineartyping</a>]<br/>
-<a href="backend.Lineartyping.html#max_over_regs_of_funct">max_over_regs_of_funct</a> [in <a href="backend.Lineartyping.html">backend.Lineartyping</a>]<br/>
-<a href="backend.Lineartyping.html#max_over_regs_of_instr">max_over_regs_of_instr</a> [in <a href="backend.Lineartyping.html">backend.Lineartyping</a>]<br/>
-<a href="backend.Lineartyping.html#max_over_slots_of_funct">max_over_slots_of_funct</a> [in <a href="backend.Lineartyping.html">backend.Lineartyping</a>]<br/>
-<a href="backend.Lineartyping.html#max_over_slots_of_instr">max_over_slots_of_instr</a> [in <a href="backend.Lineartyping.html">backend.Lineartyping</a>]<br/>
-<a href="lib.Integers.html#max_signed">max_signed</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#max_unsigned">max_unsigned</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Sets.html#mem">mem</a> [in <a href="lib.Sets.html">lib.Sets</a>]<br/>
-<a href="backend.RTLtyping.html#member">member</a> [in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.Mem.html#meminj">meminj</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#mem_chunk">mem_chunk</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Machabstr.html#mem_type">mem_type</a> [in <a href="backend.Machabstr.html">backend.Machabstr</a>]<br/>
-<a href="backend.Parallelmove.html#mesure">mesure</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="lib.Integers.html#min_signed">min_signed</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.RTLtyping.html#mk_env">mk_env</a> [in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="lib.Integers.html#mods">mods</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Cmconstr.html#mods">mods</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Values.html#mods">mods</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="lib.Integers.html#modu">modu</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Values.html#modu">modu</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Cmconstr.html#modu">modu</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="lib.Integers.html#modulus">modulus</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Cmconstr.html#mod_aux">mod_aux</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.RTLgen.html#mon">mon</a> [in <a href="backend.RTLgen.html">backend.RTLgen</a>]<br/>
-<a href="lib.Integers.html#mone">mone</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Parallelmove.html#Move">Move</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#Moves">Moves</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Lineartyping.html#mreg_bounded">mreg_bounded</a> [in <a href="backend.Lineartyping.html">backend.Lineartyping</a>]<br/>
-<a href="backend.Locations.html#mreg_type">mreg_type</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="lib.Integers.html#mul">mul</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Cmconstr.html#mul">mul</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Values.html#mul">mul</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Cmconstr.html#mulf">mulf</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Values.html#mulf">mulf</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Cmconstr.html#mulimm">mulimm</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#mulimm_base">mulimm_base</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#mulimm_match">mulimm_match</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#mul_match">mul_match</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#mul_match_aux">mul_match_aux</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.RTLgen.html#mutated_condexpr">mutated_condexpr</a> [in <a href="backend.RTLgen.html">backend.RTLgen</a>]<br/>
-<a href="backend.RTLgen.html#mutated_expr">mutated_expr</a> [in <a href="backend.RTLgen.html">backend.RTLgen</a>]<br/>
-<a href="backend.RTLgen.html#mutated_exprlist">mutated_exprlist</a> [in <a href="backend.RTLgen.html">backend.RTLgen</a>]<br/>
-<a href="backend.RTLgenproof1.html#mutated_reg">mutated_reg</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<br/><br/><a name="definition_N"></a><h2>N </h2>
-<a href="lib.Inclusion.html#nat_le_bool">nat_le_bool</a> [in <a href="lib.Inclusion.html">lib.Inclusion</a>]<br/>
-<a href="backend.Values.html#neg">neg</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="lib.Integers.html#neg">neg</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.AST.html#negate_comparison">negate_comparison</a> [in <a href="backend.AST.html">backend.AST</a>]<br/>
-<a href="backend.Op.html#negate_condition">negate_condition</a> [in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Values.html#negf">negf</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Cmconstr.html#negfloat">negfloat</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#negint">negint</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.RTLgen.html#new_reg">new_reg</a> [in <a href="backend.RTLgen.html">backend.RTLgen</a>]<br/>
-<a href="backend.PPC.html#nextinstr">nextinstr</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.Parallelmove.html#nil">nil</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#nil">nil</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#nil">nil</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#nil">nil</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#nil">nil</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#nil">nil</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#nil">nil</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#nil">nil</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#nil">nil</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#nil">nil</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Allocproof_aux.html#nil">nil</a> [in <a href="backend.Allocproof_aux.html">backend.Allocproof_aux</a>]<br/>
-<a href="backend.Parallelmove.html#nil">nil</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#nil">nil</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#nil">nil</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#nil">nil</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#nil">nil</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#nil">nil</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#nil">nil</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.RTL.html#node">node</a> [in <a href="backend.RTL.html">backend.RTL</a>]<br/>
-<a href="backend.LTL.html#node">node</a> [in <a href="backend.LTL.html">backend.LTL</a>]<br/>
-<a href="backend.Parallelmove.html#NoOverlap">NoOverlap</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#noOverlap">noOverlap</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#noOverlap_aux">noOverlap_aux</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#noRead">noRead</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="lib.Integers.html#not">not</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Values.html#notbool">notbool</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Cmconstr.html#notbool">notbool</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="lib.Integers.html#notbool">notbool</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Cmconstr.html#notbool_base">notbool_base</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Parallelmove.html#notemporary">notemporary</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Locations.html#notin">notin</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Values.html#notint">notint</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Cmconstr.html#notint">notint</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#notint_match">notint_match</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Parallelmove.html#noTmp">noTmp</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#noTmpLast">noTmpLast</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#noWrite">noWrite</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#no_overlap">no_overlap</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Locations.html#no_overlap">no_overlap</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Parallelmove.html#no_overlap_list">no_overlap_list</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#no_overlap_state">no_overlap_state</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Allocproof_aux.html#no_overlap_stateD">no_overlap_stateD</a> [in <a href="backend.Allocproof_aux.html">backend.Allocproof_aux</a>]<br/>
-<a href="backend.Allocproof_aux.html#no_tmp13_state">no_tmp13_state</a> [in <a href="backend.Allocproof_aux.html">backend.Allocproof_aux</a>]<br/>
-<a href="backend.Mem.html#nullptr">nullptr</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.CSE.html#numbering_holds">numbering_holds</a> [in <a href="backend.CSE.html">backend.CSE</a>]<br/>
-<a href="backend.CSE.html#numbering_satisfiable">numbering_satisfiable</a> [in <a href="backend.CSE.html">backend.CSE</a>]<br/>
-<a href="backend.Kildall.html#num_iterations">num_iterations</a> [in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<br/><br/><a name="definition_O"></a><h2>O </h2>
-<a href="backend.Stacking.html#offset_of_index">offset_of_index</a> [in <a href="backend.Stacking.html">backend.Stacking</a>]<br/>
-<a href="backend.Op.html#offset_sp">offset_sp</a> [in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Values.html#of_bool">of_bool</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="lib.Integers.html#one">one</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#one_bits">one_bits</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.RTLtyping.html#option_fold2">option_fold2</a> [in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="lib.Coqlib.html#option_map">option_map</a> [in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="backend.Constprop.html#op_strength_reduction">op_strength_reduction</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Constprop.html#op_strength_reduction_match">op_strength_reduction_match</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="lib.Integers.html#or">or</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Values.html#or">or</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Cmconstr.html#or">or</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.InterfGraph.html#ordered_pair">ordered_pair</a> [in <a href="backend.InterfGraph.html">backend.InterfGraph</a>]<br/>
-<a href="backend.PPCgen.html#orimm">orimm</a> [in <a href="backend.PPCgen.html">backend.PPCgen</a>]<br/>
-<a href="backend.Cmconstr.html#or_match">or_match</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Csharpminor.html#outcome_block">outcome_block</a> [in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Cminor.html#outcome_block">outcome_block</a> [in <a href="backend.Cminor.html">backend.Cminor</a>]<br/>
-<a href="backend.RTLgenproof.html#outcome_node">outcome_node</a> [in <a href="backend.RTLgenproof.html">backend.RTLgenproof</a>]<br/>
-<a href="backend.Cminor.html#outcome_result_value">outcome_result_value</a> [in <a href="backend.Cminor.html">backend.Cminor</a>]<br/>
-<a href="backend.Csharpminor.html#outcome_result_value">outcome_result_value</a> [in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Lineartyping.html#outgoing_slot">outgoing_slot</a> [in <a href="backend.Lineartyping.html">backend.Lineartyping</a>]<br/>
-<a href="backend.Lineartyping.html#outgoing_space">outgoing_space</a> [in <a href="backend.Lineartyping.html">backend.Lineartyping</a>]<br/>
-<a href="backend.Locations.html#overlap">overlap</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#overlap_aux">overlap_aux</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<br/><br/><a name="definition_P"></a><h2>P </h2>
-<a href="backend.Allocation.html#parallel_move">parallel_move</a> [in <a href="backend.Allocation.html">backend.Allocation</a>]<br/>
-<a href="backend.Allocation.html#parallel_move_order">parallel_move_order</a> [in <a href="backend.Allocation.html">backend.Allocation</a>]<br/>
-<a href="backend.Conventions.html#parameter_of_argument">parameter_of_argument</a> [in <a href="backend.Conventions.html">backend.Conventions</a>]<br/>
-<a href="backend.Parallelmove.html#path">path</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="lib.Coqlib.html#peq">peq</a> [in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="backend.Parallelmove.html#pexec">pexec</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="lib.Coqlib.html#Ple">Ple</a> [in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#Plt">Plt</a> [in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#plt">plt</a> [in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="backend.Parallelmove.html#Pmov">Pmov</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="lib.Coqlib.html#positive_rec">positive_rec</a> [in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Integers.html#powerserie">powerserie</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Kildall.html#predecessors">predecessors</a> [in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.PPCgenproof1.html#preg_of">preg_of</a> [in <a href="backend.PPCgenproof1.html">backend.PPCgenproof1</a>]<br/>
-<a href="backend.LTL.html#program">program</a> [in <a href="backend.LTL.html">backend.LTL</a>]<br/>
-<a href="backend.Cminor.html#program">program</a> [in <a href="backend.Cminor.html">backend.Cminor</a>]<br/>
-<a href="backend.Linear.html#program">program</a> [in <a href="backend.Linear.html">backend.Linear</a>]<br/>
-<a href="backend.RTL.html#program">program</a> [in <a href="backend.RTL.html">backend.RTL</a>]<br/>
-<a href="backend.Csharpminor.html#program">program</a> [in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.PPC.html#program">program</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.Mach.html#program">program</a> [in <a href="backend.Mach.html">backend.Mach</a>]<br/>
-<a href="backend.Kildall.html#propagate_succ">propagate_succ</a> [in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Kildall.html#propagate_successors">propagate_successors</a> [in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Kildall.html#propagate_succ_list">propagate_succ_list</a> [in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Kildall.html#Pstate">Pstate</a> [in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Allocproof_aux.html#p_move">p_move</a> [in <a href="backend.Allocproof_aux.html">backend.Allocproof_aux</a>]<br/>
-<a href="backend.Parallelmove.html#P_move">P_move</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<br/><br/><a name="definition_R"></a><h2>R </h2>
-<a href="backend.Coloring.html#R">R</a> [in <a href="backend.Coloring.html">backend.Coloring</a>]<br/>
-<a href="backend.Linearize.html#reachable">reachable</a> [in <a href="backend.Linearize.html">backend.Linearize</a>]<br/>
-<a href="backend.Linearize.html#reachable_aux">reachable_aux</a> [in <a href="backend.Linearize.html">backend.Linearize</a>]<br/>
-<a href="backend.Registers.html#reg">reg</a> [in <a href="backend.Registers.html">backend.Registers</a>]<br/>
-<a href="backend.Parallelmove.html#Reg">Reg</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Coloring.html#regalloc">regalloc</a> [in <a href="backend.Coloring.html">backend.Coloring</a>]<br/>
-<a href="backend.RTLtyping.html#regenv">regenv</a> [in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.LTL.html#reglist">reglist</a> [in <a href="backend.LTL.html">backend.LTL</a>]<br/>
-<a href="backend.Registers.html#regmap_optget">regmap_optget</a> [in <a href="backend.Registers.html">backend.Registers</a>]<br/>
-<a href="backend.Registers.html#regmap_optset">regmap_optset</a> [in <a href="backend.Registers.html">backend.Registers</a>]<br/>
-<a href="backend.Mach.html#regset">regset</a> [in <a href="backend.Mach.html">backend.Mach</a>]<br/>
-<a href="backend.RTL.html#regset">regset</a> [in <a href="backend.RTL.html">backend.RTL</a>]<br/>
-<a href="backend.PPC.html#regset">regset</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.Allocation.html#regs_for">regs_for</a> [in <a href="backend.Allocation.html">backend.Allocation</a>]<br/>
-<a href="backend.Allocation.html#regs_for_rec">regs_for_rec</a> [in <a href="backend.Allocation.html">backend.Allocation</a>]<br/>
-<a href="backend.Constpropproof.html#regs_match_approx">regs_match_approx</a> [in <a href="backend.Constpropproof.html">backend.Constpropproof</a>]<br/>
-<a href="backend.Lineartyping.html#regs_of_instr">regs_of_instr</a> [in <a href="backend.Lineartyping.html">backend.Lineartyping</a>]<br/>
-<a href="backend.Allocation.html#reg_for">reg_for</a> [in <a href="backend.Allocation.html">backend.Allocation</a>]<br/>
-<a href="backend.RTLgenproof1.html#reg_fresh">reg_fresh</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof1.html#reg_in_map">reg_in_map</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.Allocation.html#reg_list_dead">reg_list_dead</a> [in <a href="backend.Allocation.html">backend.Allocation</a>]<br/>
-<a href="backend.Allocation.html#reg_list_live">reg_list_live</a> [in <a href="backend.Allocation.html">backend.Allocation</a>]<br/>
-<a href="backend.PPC.html#reg_of_crbit">reg_of_crbit</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.Allocation.html#reg_option_live">reg_option_live</a> [in <a href="backend.Allocation.html">backend.Allocation</a>]<br/>
-<a href="backend.Allocation.html#reg_sum_live">reg_sum_live</a> [in <a href="backend.Allocation.html">backend.Allocation</a>]<br/>
-<a href="backend.RTLgenproof1.html#reg_valid">reg_valid</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.CSE.html#reg_valnum">reg_valnum</a> [in <a href="backend.CSE.html">backend.CSE</a>]<br/>
-<a href="lib.Sets.html#remove">remove</a> [in <a href="lib.Sets.html">lib.Sets</a>]<br/>
-<a href="lib.Maps.html#remove">remove</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Inclusion.html#remove_all_leaves">remove_all_leaves</a> [in <a href="lib.Inclusion.html">lib.Inclusion</a>]<br/>
-<a href="backend.RTLtyping.html#repet">repet</a> [in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.Parallelmove.html#replace_last_s">replace_last_s</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="lib.union_find.html#repr">repr</a> [in <a href="lib.union_find.html">lib.union_find</a>]<br/>
-<a href="lib.Integers.html#repr">repr</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.union_find.html#repr_aux">repr_aux</a> [in <a href="lib.union_find.html">lib.union_find</a>]<br/>
-<a href="lib.union_find.html#repr_order">repr_order</a> [in <a href="lib.union_find.html">lib.union_find</a>]<br/>
-<a href="lib.union_find.html#repr_rec">repr_rec</a> [in <a href="lib.union_find.html">lib.union_find</a>]<br/>
-<a href="backend.RTLgen.html#reserve_instr">reserve_instr</a> [in <a href="backend.RTLgen.html">backend.RTLgen</a>]<br/>
-<a href="backend.Stacking.html#restore_callee_save">restore_callee_save</a> [in <a href="backend.Stacking.html">backend.Stacking</a>]<br/>
-<a href="backend.Stacking.html#restore_float_callee_save">restore_float_callee_save</a> [in <a href="backend.Stacking.html">backend.Stacking</a>]<br/>
-<a href="backend.Stacking.html#restore_int_callee_save">restore_int_callee_save</a> [in <a href="backend.Stacking.html">backend.Stacking</a>]<br/>
-<a href="backend.Kildall.html#result">result</a> [in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Allocproof_aux.html#reswellFormed">reswellFormed</a> [in <a href="backend.Allocproof_aux.html">backend.Allocproof_aux</a>]<br/>
-<a href="backend.RTLgen.html#ret">ret</a> [in <a href="backend.RTLgen.html">backend.RTLgen</a>]<br/>
-<a href="backend.LTL.html#return_regs">return_regs</a> [in <a href="backend.LTL.html">backend.LTL</a>]<br/>
-<a href="backend.RTLgen.html#ret_reg">ret_reg</a> [in <a href="backend.RTLgen.html">backend.RTLgen</a>]<br/>
-<a href="backend.CSEproof.html#rhs_evals_to">rhs_evals_to</a> [in <a href="backend.CSEproof.html">backend.CSEproof</a>]<br/>
-<a href="backend.Parallelmove.html#right">right</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="lib.Integers.html#rlw_accepting">rlw_accepting</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#rlw_transition">rlw_transition</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#rol">rol</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Values.html#rolm">rolm</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Cmconstr.html#rolm">rolm</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="lib.Integers.html#rolm">rolm</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Cmconstr.html#rolm_match">rolm_match</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<br/><br/><a name="definition_S"></a><h2>S </h2>
-<a href="lib.union_find.html#sameclass">sameclass</a> [in <a href="lib.union_find.html">lib.union_find</a>]<br/>
-<a href="lib.union_find.html#sameclass">sameclass</a> [in <a href="lib.union_find.html">lib.union_find</a>]<br/>
-<a href="backend.Parallelmove.html#sameEnv">sameEnv</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#sameExec">sameExec</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Cmconstr.html#same_expr_pure">same_expr_pure</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Coloring.html#same_typ">same_typ</a> [in <a href="backend.Coloring.html">backend.Coloring</a>]<br/>
-<a href="backend.Stacking.html#save_callee_save">save_callee_save</a> [in <a href="backend.Stacking.html">backend.Stacking</a>]<br/>
-<a href="backend.Stacking.html#save_float_callee_save">save_float_callee_save</a> [in <a href="backend.Stacking.html">backend.Stacking</a>]<br/>
-<a href="backend.Stacking.html#save_int_callee_save">save_int_callee_save</a> [in <a href="backend.Stacking.html">backend.Stacking</a>]<br/>
-<a href="lib.Maps.html#set">set</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="backend.Locations.html#set">set</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="lib.Maps.html#set">set</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#set">set</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Lattice.html#set">set</a> [in <a href="lib.Lattice.html">lib.Lattice</a>]<br/>
-<a href="lib.Maps.html#set">set</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="backend.Mem.html#setN">setN</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#set_cont">set_cont</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Cminor.html#set_locals">set_locals</a> [in <a href="backend.Cminor.html">backend.Cminor</a>]<br/>
-<a href="backend.Cminor.html#set_params">set_params</a> [in <a href="backend.Cminor.html">backend.Cminor</a>]<br/>
-<a href="backend.Parallelmove.html#Sexec">Sexec</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#sexec">sexec</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Cmconstr.html#shift_match">shift_match</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Stackingproof.html#shift_sp">shift_sp</a> [in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="lib.Integers.html#shl">shl</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Cmconstr.html#shl">shl</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Values.html#shl">shl</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Cmconstr.html#shlimm">shlimm</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="lib.Integers.html#shr">shr</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Cmconstr.html#shr">shr</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Values.html#shr">shr</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Cmconstr.html#shru">shru</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="lib.Integers.html#shru">shru</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Values.html#shru">shru</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Cmconstr.html#shruimm">shruimm</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="lib.Integers.html#shrx">shrx</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Values.html#shrx">shrx</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Values.html#shr_carry">shr_carry</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="lib.Integers.html#shr_carry">shr_carry</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#signed">signed</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Parallelmove.html#simpleDest">simpleDest</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Values.html#singleoffloat">singleoffloat</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Cmconstr.html#singleoffloat">singleoffloat</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Csharpminor.html#sizeof">sizeof</a> [in <a href="backend.Csharpminor.html">backend.Csharpminor</a>]<br/>
-<a href="backend.Conventions.html#size_arguments">size_arguments</a> [in <a href="backend.Conventions.html">backend.Conventions</a>]<br/>
-<a href="backend.Conventions.html#size_arguments_rec">size_arguments_rec</a> [in <a href="backend.Conventions.html">backend.Conventions</a>]<br/>
-<a href="backend.Mem.html#size_chunk">size_chunk</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Mem.html#size_mem">size_mem</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Lineartyping.html#slots_of_instr">slots_of_instr</a> [in <a href="backend.Lineartyping.html">backend.Lineartyping</a>]<br/>
-<a href="backend.Lineartyping.html#slot_bounded">slot_bounded</a> [in <a href="backend.Lineartyping.html">backend.Lineartyping</a>]<br/>
-<a href="backend.LTLtyping.html#slot_bounded">slot_bounded</a> [in <a href="backend.LTLtyping.html">backend.LTLtyping</a>]<br/>
-<a href="backend.Locations.html#slot_type">slot_type</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Parallelmove.html#Some">Some</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="lib.Inclusion.html#sort_bin">sort_bin</a> [in <a href="lib.Inclusion.html">lib.Inclusion</a>]<br/>
-<a href="backend.Parallelmove.html#split_move">split_move</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#split_move'">split_move'</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Linearize.html#starts_with">starts_with</a> [in <a href="backend.Linearize.html">backend.Linearize</a>]<br/>
-<a href="backend.Kildall.html#start_state">start_state</a> [in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Kildall.html#start_state_in">start_state_in</a> [in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Kildall.html#start_state_wrk">start_state_wrk</a> [in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Parallelmove.html#State">State</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#StateBeing">StateBeing</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#StateDone">StateDone</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#StateToMove">StateToMove</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.RTLgenproof1.html#state_extends">state_extends</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.Kildall.html#state_invariant">state_invariant</a> [in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Kildall.html#step">step</a> [in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Kildall.html#step">step</a> [in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Parallelmove.html#stepf">stepf</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#stepf'">stepf'</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#stepInv">stepInv</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Parallelmove.html#step_NF">step_NF</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.Cmconstr.html#store">store</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Mem.html#store">store</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.PPCgen.html#storeind">storeind</a> [in <a href="backend.PPCgen.html">backend.PPCgen</a>]<br/>
-<a href="backend.PPCgen.html#storeind_aux">storeind_aux</a> [in <a href="backend.PPCgen.html">backend.PPCgen</a>]<br/>
-<a href="backend.Mem.html#storev">storev</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.PPC.html#store1">store1</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#store2">store2</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.Mem.html#store_contents">store_contents</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Cminorgen.html#store_parameters">store_parameters</a> [in <a href="backend.Cminorgen.html">backend.Cminorgen</a>]<br/>
-<a href="backend.Mach.html#store_stack">store_stack</a> [in <a href="backend.Mach.html">backend.Mach</a>]<br/>
-<a href="backend.Values.html#sub">sub</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="lib.Integers.html#sub">sub</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Cmconstr.html#sub">sub</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Values.html#subf">subf</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Cmconstr.html#subf">subf</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#subf_match">subf_match</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#sub_match">sub_match</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Cmconstr.html#sub_match_aux">sub_match_aux</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.LTL.html#successors">successors</a> [in <a href="backend.LTL.html">backend.LTL</a>]<br/>
-<a href="backend.RTL.html#successors">successors</a> [in <a href="backend.RTL.html">backend.RTL</a>]<br/>
-<a href="backend.LTL.html#successors_aux">successors_aux</a> [in <a href="backend.LTL.html">backend.LTL</a>]<br/>
-<a href="lib.Coqlib.html#sum_left_map">sum_left_map</a> [in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="backend.AST.html#swap_comparison">swap_comparison</a> [in <a href="backend.AST.html">backend.AST</a>]<br/>
-<a href="backend.PPC.html#symbol_offset">symbol_offset</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.Linearize.html#s1">s1</a> [in <a href="backend.Linearize.html">backend.Linearize</a>]<br/>
-<br/><br/><a name="definition_T"></a><h2>T </h2>
-<a href="backend.PPC.html#t">t</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="lib.Ordered.html#t">t</a> [in <a href="lib.Ordered.html">lib.Ordered</a>]<br/>
-<a href="lib.Maps.html#t">t</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#t">t</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Lattice.html#t">t</a> [in <a href="lib.Lattice.html">lib.Lattice</a>]<br/>
-<a href="backend.Locations.html#t">t</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Constprop.html#t">t</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="lib.Ordered.html#t">t</a> [in <a href="lib.Ordered.html">lib.Ordered</a>]<br/>
-<a href="backend.Globalenvs.html#t">t</a> [in <a href="backend.Globalenvs.html">backend.Globalenvs</a>]<br/>
-<a href="lib.Lattice.html#t">t</a> [in <a href="lib.Lattice.html">lib.Lattice</a>]<br/>
-<a href="backend.RTLtyping.html#T">T</a> [in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="lib.union_find.html#T">T</a> [in <a href="lib.union_find.html">lib.union_find</a>]<br/>
-<a href="backend.CSEproof.html#t">t</a> [in <a href="backend.CSEproof.html">backend.CSEproof</a>]<br/>
-<a href="backend.Locations.html#t">t</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="lib.Maps.html#t">t</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="backend.Parallelmove.html#T">T</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="lib.Maps.html#t">t</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="backend.RTLtyping.html#T">T</a> [in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.InterfGraph.html#t">t</a> [in <a href="backend.InterfGraph.html">backend.InterfGraph</a>]<br/>
-<a href="lib.Maps.html#t">t</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Ordered.html#t">t</a> [in <a href="lib.Ordered.html">lib.Ordered</a>]<br/>
-<a href="lib.Lattice.html#t">t</a> [in <a href="lib.Lattice.html">lib.Lattice</a>]<br/>
-<a href="backend.Mach.html#t">t</a> [in <a href="backend.Mach.html">backend.Mach</a>]<br/>
-<a href="lib.Sets.html#t">t</a> [in <a href="lib.Sets.html">lib.Sets</a>]<br/>
-<a href="lib.Maps.html#t">t</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="backend.CSE.html#t">t</a> [in <a href="backend.CSE.html">backend.CSE</a>]<br/>
-<a href="backend.Conventions.html#temporaries">temporaries</a> [in <a href="backend.Conventions.html">backend.Conventions</a>]<br/>
-<a href="backend.Allocproof_aux.html#temporaries1">temporaries1</a> [in <a href="backend.Allocproof_aux.html">backend.Allocproof_aux</a>]<br/>
-<a href="backend.Allocproof_aux.html#temporaries1_3">temporaries1_3</a> [in <a href="backend.Allocproof_aux.html">backend.Allocproof_aux</a>]<br/>
-<a href="backend.Allocproof_aux.html#temporaries2">temporaries2</a> [in <a href="backend.Allocproof_aux.html">backend.Allocproof_aux</a>]<br/>
-<a href="backend.RTLtyping.html#teq">teq</a> [in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="lib.Inclusion.html#test_inclusion">test_inclusion</a> [in <a href="lib.Inclusion.html">lib.Inclusion</a>]<br/>
-<a href="backend.Allocation.html#Tint">Tint</a> [in <a href="backend.Allocation.html">backend.Allocation</a>]<br/>
-<a href="lib.Lattice.html#top">top</a> [in <a href="lib.Lattice.html">lib.Lattice</a>]<br/>
-<a href="lib.Lattice.html#top">top</a> [in <a href="lib.Lattice.html">lib.Lattice</a>]<br/>
-<a href="backend.CSE.html#top">top</a> [in <a href="backend.CSE.html">backend.CSE</a>]<br/>
-<a href="backend.Constprop.html#top">top</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="lib.Lattice.html#top">top</a> [in <a href="lib.Lattice.html">lib.Lattice</a>]<br/>
-<a href="backend.Allocation.html#transfer">transfer</a> [in <a href="backend.Allocation.html">backend.Allocation</a>]<br/>
-<a href="backend.Constprop.html#transfer">transfer</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.CSE.html#transfer">transfer</a> [in <a href="backend.CSE.html">backend.CSE</a>]<br/>
-<a href="backend.AST.html#transform_partial_program">transform_partial_program</a> [in <a href="backend.AST.html">backend.AST</a>]<br/>
-<a href="backend.AST.html#transform_program">transform_program</a> [in <a href="backend.AST.html">backend.AST</a>]<br/>
-<a href="backend.Main.html#transf_cminor_function">transf_cminor_function</a> [in <a href="backend.Main.html">backend.Main</a>]<br/>
-<a href="backend.Main.html#transf_cminor_program">transf_cminor_program</a> [in <a href="backend.Main.html">backend.Main</a>]<br/>
-<a href="backend.Main.html#transf_cminor_program2">transf_cminor_program2</a> [in <a href="backend.Main.html">backend.Main</a>]<br/>
-<a href="backend.Constprop.html#transf_code">transf_code</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.CSE.html#transf_code">transf_code</a> [in <a href="backend.CSE.html">backend.CSE</a>]<br/>
-<a href="backend.Main.html#transf_csharpminor_function">transf_csharpminor_function</a> [in <a href="backend.Main.html">backend.Main</a>]<br/>
-<a href="backend.Main.html#transf_csharpminor_program">transf_csharpminor_program</a> [in <a href="backend.Main.html">backend.Main</a>]<br/>
-<a href="backend.Main.html#transf_csharpminor_program2">transf_csharpminor_program2</a> [in <a href="backend.Main.html">backend.Main</a>]<br/>
-<a href="backend.Allocation.html#transf_entrypoint">transf_entrypoint</a> [in <a href="backend.Allocation.html">backend.Allocation</a>]<br/>
-<a href="backend.Linearize.html#transf_function">transf_function</a> [in <a href="backend.Linearize.html">backend.Linearize</a>]<br/>
-<a href="backend.Allocation.html#transf_function">transf_function</a> [in <a href="backend.Allocation.html">backend.Allocation</a>]<br/>
-<a href="backend.CSE.html#transf_function">transf_function</a> [in <a href="backend.CSE.html">backend.CSE</a>]<br/>
-<a href="backend.RTL.html#transf_function">transf_function</a> [in <a href="backend.RTL.html">backend.RTL</a>]<br/>
-<a href="backend.PPCgen.html#transf_function">transf_function</a> [in <a href="backend.PPCgen.html">backend.PPCgen</a>]<br/>
-<a href="backend.Stacking.html#transf_function">transf_function</a> [in <a href="backend.Stacking.html">backend.Stacking</a>]<br/>
-<a href="backend.Constprop.html#transf_function">transf_function</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Allocation.html#transf_instr">transf_instr</a> [in <a href="backend.Allocation.html">backend.Allocation</a>]<br/>
-<a href="backend.Constprop.html#transf_instr">transf_instr</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.CSE.html#transf_instr">transf_instr</a> [in <a href="backend.CSE.html">backend.CSE</a>]<br/>
-<a href="backend.Globalenvs.html#transf_partial">transf_partial</a> [in <a href="backend.Globalenvs.html">backend.Globalenvs</a>]<br/>
-<a href="backend.AST.html#transf_partial_program">transf_partial_program</a> [in <a href="backend.AST.html">backend.AST</a>]<br/>
-<a href="backend.CSE.html#transf_program">transf_program</a> [in <a href="backend.CSE.html">backend.CSE</a>]<br/>
-<a href="backend.PPCgen.html#transf_program">transf_program</a> [in <a href="backend.PPCgen.html">backend.PPCgen</a>]<br/>
-<a href="backend.Stacking.html#transf_program">transf_program</a> [in <a href="backend.Stacking.html">backend.Stacking</a>]<br/>
-<a href="backend.Constprop.html#transf_program">transf_program</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Allocation.html#transf_program">transf_program</a> [in <a href="backend.Allocation.html">backend.Allocation</a>]<br/>
-<a href="backend.Linearize.html#transf_program">transf_program</a> [in <a href="backend.Linearize.html">backend.Linearize</a>]<br/>
-<a href="backend.AST.html#transf_program">transf_program</a> [in <a href="backend.AST.html">backend.AST</a>]<br/>
-<a href="backend.Stacking.html#transl_addr">transl_addr</a> [in <a href="backend.Stacking.html">backend.Stacking</a>]<br/>
-<a href="backend.Stacking.html#transl_body">transl_body</a> [in <a href="backend.Stacking.html">backend.Stacking</a>]<br/>
-<a href="backend.PPCgen.html#transl_code">transl_code</a> [in <a href="backend.PPCgen.html">backend.PPCgen</a>]<br/>
-<a href="backend.Stacking.html#transl_code">transl_code</a> [in <a href="backend.Stacking.html">backend.Stacking</a>]<br/>
-<a href="backend.PPCgen.html#transl_cond">transl_cond</a> [in <a href="backend.PPCgen.html">backend.PPCgen</a>]<br/>
-<a href="backend.RTLgenproof.html#transl_condition_correct">transl_condition_correct</a> [in <a href="backend.RTLgenproof.html">backend.RTLgenproof</a>]<br/>
-<a href="backend.RTLgenproof1.html#transl_condition_incr_pred">transl_condition_incr_pred</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgen.html#transl_expr">transl_expr</a> [in <a href="backend.RTLgen.html">backend.RTLgen</a>]<br/>
-<a href="backend.Cminorgen.html#transl_expr">transl_expr</a> [in <a href="backend.Cminorgen.html">backend.Cminorgen</a>]<br/>
-<a href="backend.RTLgenproof.html#transl_exprlist_correct">transl_exprlist_correct</a> [in <a href="backend.RTLgenproof.html">backend.RTLgenproof</a>]<br/>
-<a href="backend.RTLgenproof1.html#transl_exprlist_incr_pred">transl_exprlist_incr_pred</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof.html#transl_expr_correct">transl_expr_correct</a> [in <a href="backend.RTLgenproof.html">backend.RTLgenproof</a>]<br/>
-<a href="backend.RTLgenproof1.html#transl_expr_incr_pred">transl_expr_incr_pred</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgen.html#transl_fun">transl_fun</a> [in <a href="backend.RTLgen.html">backend.RTLgen</a>]<br/>
-<a href="backend.Cminorgen.html#transl_function">transl_function</a> [in <a href="backend.Cminorgen.html">backend.Cminorgen</a>]<br/>
-<a href="backend.PPCgen.html#transl_function">transl_function</a> [in <a href="backend.PPCgen.html">backend.PPCgen</a>]<br/>
-<a href="backend.RTLgen.html#transl_function">transl_function</a> [in <a href="backend.RTLgen.html">backend.RTLgen</a>]<br/>
-<a href="backend.RTLgenproof.html#transl_function_correct">transl_function_correct</a> [in <a href="backend.RTLgenproof.html">backend.RTLgenproof</a>]<br/>
-<a href="backend.PPCgen.html#transl_instr">transl_instr</a> [in <a href="backend.PPCgen.html">backend.PPCgen</a>]<br/>
-<a href="backend.Stacking.html#transl_instr">transl_instr</a> [in <a href="backend.Stacking.html">backend.Stacking</a>]<br/>
-<a href="backend.PPCgen.html#transl_load_store">transl_load_store</a> [in <a href="backend.PPCgen.html">backend.PPCgen</a>]<br/>
-<a href="backend.Stacking.html#transl_op">transl_op</a> [in <a href="backend.Stacking.html">backend.Stacking</a>]<br/>
-<a href="backend.PPCgen.html#transl_op">transl_op</a> [in <a href="backend.PPCgen.html">backend.PPCgen</a>]<br/>
-<a href="backend.RTLgen.html#transl_program">transl_program</a> [in <a href="backend.RTLgen.html">backend.RTLgen</a>]<br/>
-<a href="backend.Cminorgen.html#transl_program">transl_program</a> [in <a href="backend.Cminorgen.html">backend.Cminorgen</a>]<br/>
-<a href="backend.Cminorgen.html#transl_stmt">transl_stmt</a> [in <a href="backend.Cminorgen.html">backend.Cminorgen</a>]<br/>
-<a href="backend.RTLgen.html#transl_stmt">transl_stmt</a> [in <a href="backend.RTLgen.html">backend.RTLgen</a>]<br/>
-<a href="backend.RTLgenproof.html#transl_stmtlist_correct">transl_stmtlist_correct</a> [in <a href="backend.RTLgenproof.html">backend.RTLgenproof</a>]<br/>
-<a href="backend.RTLgenproof1.html#transl_stmtlist_incr_pred">transl_stmtlist_incr_pred</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.RTLgenproof.html#transl_stmt_correct">transl_stmt_correct</a> [in <a href="backend.RTLgenproof.html">backend.RTLgenproof</a>]<br/>
-<a href="backend.RTLgenproof1.html#transl_stmt_incr_pred">transl_stmt_incr_pred</a> [in <a href="backend.RTLgenproof1.html">backend.RTLgenproof1</a>]<br/>
-<a href="backend.Tunnelingproof.html#tunneled_code">tunneled_code</a> [in <a href="backend.Tunnelingproof.html">backend.Tunnelingproof</a>]<br/>
-<a href="backend.Tunneling.html#tunnel_block">tunnel_block</a> [in <a href="backend.Tunneling.html">backend.Tunneling</a>]<br/>
-<a href="backend.Tunneling.html#tunnel_function">tunnel_function</a> [in <a href="backend.Tunneling.html">backend.Tunneling</a>]<br/>
-<a href="backend.Tunnelingproof.html#tunnel_outcome">tunnel_outcome</a> [in <a href="backend.Tunnelingproof.html">backend.Tunnelingproof</a>]<br/>
-<a href="backend.Tunneling.html#tunnel_program">tunnel_program</a> [in <a href="backend.Tunneling.html">backend.Tunneling</a>]<br/>
-<a href="backend.Locations.html#type">type</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Registers.html#typenv">typenv</a> [in <a href="backend.Registers.html">backend.Registers</a>]<br/>
-<a href="backend.AST.html#typesize">typesize</a> [in <a href="backend.AST.html">backend.AST</a>]<br/>
-<a href="backend.Locations.html#typesize">typesize</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Op.html#type_of_addressing">type_of_addressing</a> [in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Op.html#type_of_chunk">type_of_chunk</a> [in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Op.html#type_of_condition">type_of_condition</a> [in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.Stackingproof.html#type_of_index">type_of_index</a> [in <a href="backend.Stackingproof.html">backend.Stackingproof</a>]<br/>
-<a href="backend.Op.html#type_of_operation">type_of_operation</a> [in <a href="backend.Op.html">backend.Op</a>]<br/>
-<a href="backend.RTLtyping.html#type_of_sig_res">type_of_sig_res</a> [in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.RTLtyping.html#type_rtl_arg">type_rtl_arg</a> [in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.RTLtyping.html#type_rtl_function">type_rtl_function</a> [in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.RTLtyping.html#type_rtl_instr">type_rtl_instr</a> [in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.RTLtyping.html#type_rtl_ros">type_rtl_ros</a> [in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<br/><br/><a name="definition_U"></a><h2>U </h2>
-<a href="backend.Mem.html#unchecked_store">unchecked_store</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="lib.Sets.html#union">union</a> [in <a href="lib.Sets.html">lib.Sets</a>]<br/>
-<a href="backend.Linearizeproof.html#unique_labels">unique_labels</a> [in <a href="backend.Linearizeproof.html">backend.Linearizeproof</a>]<br/>
-<a href="lib.Integers.html#unsigned">unsigned</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Mem.html#update">update</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Parallelmove.html#update">update</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.RTLgen.html#update_instr">update_instr</a> [in <a href="backend.RTLgen.html">backend.RTLgen</a>]<br/>
-<br/><br/><a name="definition_V"></a><h2>V </h2>
-<a href="backend.Mem.html#valid_block">valid_block</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.Linearizeproof.html#valid_outcome">valid_outcome</a> [in <a href="backend.Linearizeproof.html">backend.Linearizeproof</a>]<br/>
-<a href="backend.Mem.html#valid_pointer">valid_pointer</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="backend.CSE.html#valnum">valnum</a> [in <a href="backend.CSE.html">backend.CSE</a>]<br/>
-<a href="backend.CSE.html#valnum_reg">valnum_reg</a> [in <a href="backend.CSE.html">backend.CSE</a>]<br/>
-<a href="backend.CSE.html#valnum_regs">valnum_regs</a> [in <a href="backend.CSE.html">backend.CSE</a>]<br/>
-<a href="backend.Parallelmove.html#Value">Value</a> [in <a href="backend.Parallelmove.html">backend.Parallelmove</a>]<br/>
-<a href="backend.CSEproof.html#valu_agree">valu_agree</a> [in <a href="backend.CSEproof.html">backend.CSEproof</a>]<br/>
-<a href="backend.PPC.html#val_cond_reg">val_cond_reg</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.Constpropproof.html#val_match_approx">val_match_approx</a> [in <a href="backend.Constpropproof.html">backend.Constpropproof</a>]<br/>
-<a href="backend.Cminorgenproof.html#val_normalized">val_normalized</a> [in <a href="backend.Cminorgenproof.html">backend.Cminorgenproof</a>]<br/>
-<a href="backend.Cminorgen.html#var_addr">var_addr</a> [in <a href="backend.Cminorgen.html">backend.Cminorgen</a>]<br/>
-<a href="backend.Cminorgen.html#var_get">var_get</a> [in <a href="backend.Cminorgen.html">backend.Cminorgen</a>]<br/>
-<a href="backend.Cminorgen.html#var_set">var_set</a> [in <a href="backend.Cminorgen.html">backend.Cminorgen</a>]<br/>
-<a href="backend.Values.html#Vfalse">Vfalse</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Values.html#Vmone">Vmone</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Values.html#Vone">Vone</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Values.html#Vtrue">Vtrue</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.Values.html#Vzero">Vzero</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<br/><br/><a name="definition_W"></a><h2>W </h2>
-<a href="backend.CSEproof.html#wf_equation">wf_equation</a> [in <a href="backend.CSEproof.html">backend.CSEproof</a>]<br/>
-<a href="backend.CSEproof.html#wf_numbering">wf_numbering</a> [in <a href="backend.CSEproof.html">backend.CSEproof</a>]<br/>
-<a href="backend.CSEproof.html#wf_rhs">wf_rhs</a> [in <a href="backend.CSEproof.html">backend.CSEproof</a>]<br/>
-<a href="lib.Integers.html#wordsize">wordsize</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Machtyping.html#wt_content">wt_content</a> [in <a href="backend.Machtyping.html">backend.Machtyping</a>]<br/>
-<a href="backend.Machtyping.html#wt_frame">wt_frame</a> [in <a href="backend.Machtyping.html">backend.Machtyping</a>]<br/>
-<a href="backend.LTLtyping.html#wt_function">wt_function</a> [in <a href="backend.LTLtyping.html">backend.LTLtyping</a>]<br/>
-<a href="backend.Lineartyping.html#wt_function">wt_function</a> [in <a href="backend.Lineartyping.html">backend.Lineartyping</a>]<br/>
-<a href="backend.Stackingtyping.html#wt_instrs">wt_instrs</a> [in <a href="backend.Stackingtyping.html">backend.Stackingtyping</a>]<br/>
-<a href="backend.Lineartyping.html#wt_program">wt_program</a> [in <a href="backend.Lineartyping.html">backend.Lineartyping</a>]<br/>
-<a href="backend.RTLtyping.html#wt_program">wt_program</a> [in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.LTLtyping.html#wt_program">wt_program</a> [in <a href="backend.LTLtyping.html">backend.LTLtyping</a>]<br/>
-<a href="backend.Machtyping.html#wt_program">wt_program</a> [in <a href="backend.Machtyping.html">backend.Machtyping</a>]<br/>
-<a href="backend.RTLtyping.html#wt_regset">wt_regset</a> [in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.Machtyping.html#wt_regset">wt_regset</a> [in <a href="backend.Machtyping.html">backend.Machtyping</a>]<br/>
-<br/><br/><a name="definition_X"></a><h2>X </h2>
-<a href="lib.Maps.html#xcombine_l">xcombine_l</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#xcombine_r">xcombine_r</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#xelements">xelements</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#xget">xget</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#xkeys">xkeys</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#xmap">xmap</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="backend.Cmconstr.html#xor">xor</a> [in <a href="backend.Cmconstr.html">backend.Cmconstr</a>]<br/>
-<a href="backend.Values.html#xor">xor</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="lib.Integers.html#xor">xor</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.PPCgen.html#xorimm">xorimm</a> [in <a href="backend.PPCgen.html">backend.PPCgen</a>]<br/>
-<br/><br/><a name="definition_Z"></a><h2>Z </h2>
-<a href="lib.Integers.html#Zdiv_round">Zdiv_round</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Coqlib.html#zeq">zeq</a> [in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Integers.html#zero">zero</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Coqlib.html#zle">zle</a> [in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Coqlib.html#zlt">zlt</a> [in <a href="lib.Coqlib.html">lib.Coqlib</a>]<br/>
-<a href="lib.Integers.html#Zmod_round">Zmod_round</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="backend.Mem.html#ztonat">ztonat</a> [in <a href="backend.Mem.html">backend.Mem</a>]<br/>
-<a href="lib.Integers.html#Z_bin_decomp">Z_bin_decomp</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#Z_of_bits">Z_of_bits</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#Z_one_bits">Z_one_bits</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<a href="lib.Integers.html#Z_shift_add">Z_shift_add</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<br/><br/><hr/>
-<h1>Module Index</h1>
-<a name="module_A"></a><h2>A </h2>
-<a href="backend.Constprop.html#Approx">Approx</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<br/><br/><a name="module_B"></a><h2>B </h2>
-<a href="backend.Kildall.html#BACKWARD_DATAFLOW_SOLVER">BACKWARD_DATAFLOW_SOLVER</a> [in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Kildall.html#Backward_Dataflow_Solver">Backward_Dataflow_Solver</a> [in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Kildall.html#BBlock_solver">BBlock_solver</a> [in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Kildall.html#BBLOCK_SOLVER">BBLOCK_SOLVER</a> [in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<br/><br/><a name="module_D"></a><h2>D </h2>
-<a href="backend.Constprop.html#D">D</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Kildall.html#Dataflow_Solver">Dataflow_Solver</a> [in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Kildall.html#DATAFLOW_SOLVER">DATAFLOW_SOLVER</a> [in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Kildall.html#DS">DS</a> [in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Constprop.html#DS">DS</a> [in <a href="backend.Constprop.html">backend.Constprop</a>]<br/>
-<a href="backend.Linearize.html#DS">DS</a> [in <a href="backend.Linearize.html">backend.Linearize</a>]<br/>
-<a href="backend.Allocation.html#DS">DS</a> [in <a href="backend.Allocation.html">backend.Allocation</a>]<br/>
-<br/><br/><a name="module_E"></a><h2>E </h2>
-<a href="lib.union_find.html#ELEMENT">ELEMENT</a> [in <a href="lib.union_find.html">lib.union_find</a>]<br/>
-<a href="lib.Maps.html#EMap">EMap</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#EQUALITY_TYPE">EQUALITY_TYPE</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<br/><br/><a name="module_F"></a><h2>F </h2>
-<a href="lib.Floats.html#Float">Float</a> [in <a href="lib.Floats.html">lib.Floats</a>]<br/>
-<br/><br/><a name="module_G"></a><h2>G </h2>
-<a href="backend.Globalenvs.html#Genv">Genv</a> [in <a href="backend.Globalenvs.html">backend.Globalenvs</a>]<br/>
-<a href="backend.Globalenvs.html#GENV">GENV</a> [in <a href="backend.Globalenvs.html">backend.Globalenvs</a>]<br/>
-<br/><br/><a name="module_I"></a><h2>I </h2>
-<a href="backend.Cminorgen.html#Identset">Identset</a> [in <a href="backend.Cminorgen.html">backend.Cminorgen</a>]<br/>
-<a href="lib.Maps.html#IMap">IMap</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="backend.Locations.html#IndexedMreg">IndexedMreg</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="lib.Maps.html#INDEXED_TYPE">INDEXED_TYPE</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Integers.html#Int">Int</a> [in <a href="lib.Integers.html">lib.Integers</a>]<br/>
-<br/><br/><a name="module_L"></a><h2>L </h2>
-<a href="backend.Kildall.html#L">L</a> [in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Kildall.html#L">L</a> [in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Kildall.html#L">L</a> [in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Kildall.html#L">L</a> [in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Kildall.html#L">L</a> [in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Kildall.html#L">L</a> [in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Kildall.html#L">L</a> [in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Kildall.html#L">L</a> [in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="backend.Kildall.html#L">L</a> [in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<a href="lib.Lattice.html#LBoolean">LBoolean</a> [in <a href="lib.Lattice.html">lib.Lattice</a>]<br/>
-<a href="lib.Lattice.html#LFlat">LFlat</a> [in <a href="lib.Lattice.html">lib.Lattice</a>]<br/>
-<a href="backend.Locations.html#Loc">Loc</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="backend.Locations.html#Locmap">Locmap</a> [in <a href="backend.Locations.html">backend.Locations</a>]<br/>
-<a href="lib.Lattice.html#LPMap">LPMap</a> [in <a href="lib.Lattice.html">lib.Lattice</a>]<br/>
-<br/><br/><a name="module_M"></a><h2>M </h2>
-<a href="lib.Sets.html#MakeSet">MakeSet</a> [in <a href="lib.Sets.html">lib.Sets</a>]<br/>
-<a href="lib.Maps.html#MAP">MAP</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.union_find.html#MAP">MAP</a> [in <a href="lib.union_find.html">lib.union_find</a>]<br/>
-<a href="backend.RTLtyping.html#mymap">mymap</a> [in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="backend.RTLtyping.html#myreg">myreg</a> [in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<br/><br/><a name="module_N"></a><h2>N </h2>
-<a href="lib.Maps.html#NIndexed">NIndexed</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#NMap">NMap</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="backend.CSE.html#Numbering">Numbering</a> [in <a href="backend.CSE.html">backend.CSE</a>]<br/>
-<br/><br/><a name="module_O"></a><h2>O </h2>
-<a href="lib.Ordered.html#OrderedIndexed">OrderedIndexed</a> [in <a href="lib.Ordered.html">lib.Ordered</a>]<br/>
-<a href="backend.InterfGraph.html#OrderedMreg">OrderedMreg</a> [in <a href="backend.InterfGraph.html">backend.InterfGraph</a>]<br/>
-<a href="lib.Ordered.html#OrderedPair">OrderedPair</a> [in <a href="lib.Ordered.html">lib.Ordered</a>]<br/>
-<a href="lib.Ordered.html#OrderedPositive">OrderedPositive</a> [in <a href="lib.Ordered.html">lib.Ordered</a>]<br/>
-<a href="backend.InterfGraph.html#OrderedReg">OrderedReg</a> [in <a href="backend.InterfGraph.html">backend.InterfGraph</a>]<br/>
-<a href="backend.InterfGraph.html#OrderedRegMreg">OrderedRegMreg</a> [in <a href="backend.InterfGraph.html">backend.InterfGraph</a>]<br/>
-<a href="backend.InterfGraph.html#OrderedRegReg">OrderedRegReg</a> [in <a href="backend.InterfGraph.html">backend.InterfGraph</a>]<br/>
-<a href="backend.Kildall.html#ORDERED_TYPE_WITH_TOP">ORDERED_TYPE_WITH_TOP</a> [in <a href="backend.Kildall.html">backend.Kildall</a>]<br/>
-<br/><br/><a name="module_P"></a><h2>P </h2>
-<a href="lib.Maps.html#PMap">PMap</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="backend.PPC.html#PregEq">PregEq</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="backend.PPC.html#Pregmap">Pregmap</a> [in <a href="backend.PPC.html">backend.PPC</a>]<br/>
-<a href="lib.Maps.html#PTree">PTree</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<br/><br/><a name="module_R"></a><h2>R </h2>
-<a href="backend.Registers.html#Reg">Reg</a> [in <a href="backend.Registers.html">backend.Registers</a>]<br/>
-<a href="backend.Mach.html#RegEq">RegEq</a> [in <a href="backend.Mach.html">backend.Mach</a>]<br/>
-<a href="backend.Mach.html#Regmap">Regmap</a> [in <a href="backend.Mach.html">backend.Mach</a>]<br/>
-<a href="backend.Registers.html#Regmap">Regmap</a> [in <a href="backend.Registers.html">backend.Registers</a>]<br/>
-<a href="backend.Registers.html#Regset">Regset</a> [in <a href="backend.Registers.html">backend.Registers</a>]<br/>
-<br/><br/><a name="module_S"></a><h2>S </h2>
-<a href="lib.Lattice.html#SEMILATTICE">SEMILATTICE</a> [in <a href="lib.Lattice.html">lib.Lattice</a>]<br/>
-<a href="lib.Lattice.html#SEMILATTICE_WITH_TOP">SEMILATTICE_WITH_TOP</a> [in <a href="lib.Lattice.html">lib.Lattice</a>]<br/>
-<a href="backend.InterfGraph.html#SetDepRegMreg">SetDepRegMreg</a> [in <a href="backend.InterfGraph.html">backend.InterfGraph</a>]<br/>
-<a href="backend.InterfGraph.html#SetDepRegReg">SetDepRegReg</a> [in <a href="backend.InterfGraph.html">backend.InterfGraph</a>]<br/>
-<a href="backend.InterfGraph.html#SetRegMreg">SetRegMreg</a> [in <a href="backend.InterfGraph.html">backend.InterfGraph</a>]<br/>
-<a href="backend.InterfGraph.html#SetRegReg">SetRegReg</a> [in <a href="backend.InterfGraph.html">backend.InterfGraph</a>]<br/>
-<a href="backend.CSE.html#Solver">Solver</a> [in <a href="backend.CSE.html">backend.CSE</a>]<br/>
-<br/><br/><a name="module_T"></a><h2>T </h2>
-<a href="lib.Maps.html#TREE">TREE</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<br/><br/><a name="module_U"></a><h2>U </h2>
-<a href="backend.RTLtyping.html#Uf">Uf</a> [in <a href="backend.RTLtyping.html">backend.RTLtyping</a>]<br/>
-<a href="lib.union_find.html#UNIONFIND">UNIONFIND</a> [in <a href="lib.union_find.html">lib.union_find</a>]<br/>
-<a href="lib.union_find.html#Unionfind">Unionfind</a> [in <a href="lib.union_find.html">lib.union_find</a>]<br/>
-<br/><br/><a name="module_V"></a><h2>V </h2>
-<a href="backend.Values.html#Val">Val</a> [in <a href="backend.Values.html">backend.Values</a>]<br/>
-<a href="backend.CSEproof.html#ValnumEq">ValnumEq</a> [in <a href="backend.CSEproof.html">backend.CSEproof</a>]<br/>
-<a href="backend.CSEproof.html#VMap">VMap</a> [in <a href="backend.CSEproof.html">backend.CSEproof</a>]<br/>
-<br/><br/><a name="module_Z"></a><h2>Z </h2>
-<a href="lib.Maps.html#ZIndexed">ZIndexed</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<a href="lib.Maps.html#ZMap">ZMap</a> [in <a href="lib.Maps.html">lib.Maps</a>]<br/>
-<br/><br/><hr/>
-<h1>Library Index</h1>
-<a name="library_A"></a><h2>A </h2>
-<a href="backend.Allocation.html">Allocation</a> <br/>
-<a href="backend.Allocproof.html">Allocproof</a> <br/>
-<a href="backend.Allocproof_aux.html">Allocproof_aux</a> <br/>
-<a href="backend.Alloctyping.html">Alloctyping</a> <br/>
-<a href="backend.Alloctyping_aux.html">Alloctyping_aux</a> <br/>
-<a href="backend.AST.html">AST</a> <br/>
-<br/><br/><a name="library_C"></a><h2>C </h2>
-<a href="backend.Cmconstr.html">Cmconstr</a> <br/>
-<a href="backend.Cmconstrproof.html">Cmconstrproof</a> <br/>
-<a href="backend.Cminor.html">Cminor</a> <br/>
-<a href="backend.Cminorgen.html">Cminorgen</a> <br/>
-<a href="backend.Cminorgenproof.html">Cminorgenproof</a> <br/>
-<a href="backend.Coloring.html">Coloring</a> <br/>
-<a href="backend.Coloringproof.html">Coloringproof</a> <br/>
-<a href="backend.Constprop.html">Constprop</a> <br/>
-<a href="backend.Constpropproof.html">Constpropproof</a> <br/>
-<a href="backend.Conventions.html">Conventions</a> <br/>
-<a href="lib.Coqlib.html">Coqlib</a> <br/>
-<a href="backend.CSE.html">CSE</a> <br/>
-<a href="backend.CSEproof.html">CSEproof</a> <br/>
-<a href="backend.Csharpminor.html">Csharpminor</a> <br/>
-<br/><br/><a name="library_F"></a><h2>F </h2>
-<a href="lib.Floats.html">Floats</a> <br/>
-<br/><br/><a name="library_G"></a><h2>G </h2>
-<a href="backend.Globalenvs.html">Globalenvs</a> <br/>
-<br/><br/><a name="library_I"></a><h2>I </h2>
-<a href="lib.Inclusion.html">Inclusion</a> <br/>
-<a href="lib.Integers.html">Integers</a> <br/>
-<a href="backend.InterfGraph.html">InterfGraph</a> <br/>
-<br/><br/><a name="library_K"></a><h2>K </h2>
-<a href="backend.Kildall.html">Kildall</a> <br/>
-<br/><br/><a name="library_L"></a><h2>L </h2>
-<a href="lib.Lattice.html">Lattice</a> <br/>
-<a href="backend.Linear.html">Linear</a> <br/>
-<a href="backend.Linearize.html">Linearize</a> <br/>
-<a href="backend.Linearizeproof.html">Linearizeproof</a> <br/>
-<a href="backend.Linearizetyping.html">Linearizetyping</a> <br/>
-<a href="backend.Lineartyping.html">Lineartyping</a> <br/>
-<a href="backend.Locations.html">Locations</a> <br/>
-<a href="backend.LTL.html">LTL</a> <br/>
-<a href="backend.LTLtyping.html">LTLtyping</a> <br/>
-<br/><br/><a name="library_M"></a><h2>M </h2>
-<a href="backend.Mach.html">Mach</a> <br/>
-<a href="backend.Machabstr.html">Machabstr</a> <br/>
-<a href="backend.Machabstr2mach.html">Machabstr2mach</a> <br/>
-<a href="backend.Machtyping.html">Machtyping</a> <br/>
-<a href="backend.Main.html">Main</a> <br/>
-<a href="lib.Maps.html">Maps</a> <br/>
-<a href="backend.Mem.html">Mem</a> <br/>
-<br/><br/><a name="library_O"></a><h2>O </h2>
-<a href="backend.Op.html">Op</a> <br/>
-<a href="lib.Ordered.html">Ordered</a> <br/>
-<br/><br/><a name="library_P"></a><h2>P </h2>
-<a href="backend.Parallelmove.html">Parallelmove</a> <br/>
-<a href="backend.PPC.html">PPC</a> <br/>
-<a href="backend.PPCgen.html">PPCgen</a> <br/>
-<a href="backend.PPCgenproof.html">PPCgenproof</a> <br/>
-<a href="backend.PPCgenproof1.html">PPCgenproof1</a> <br/>
-<br/><br/><a name="library_R"></a><h2>R </h2>
-<a href="backend.Registers.html">Registers</a> <br/>
-<a href="backend.RTL.html">RTL</a> <br/>
-<a href="backend.RTLgen.html">RTLgen</a> <br/>
-<a href="backend.RTLgenproof.html">RTLgenproof</a> <br/>
-<a href="backend.RTLgenproof1.html">RTLgenproof1</a> <br/>
-<a href="backend.RTLtyping.html">RTLtyping</a> <br/>
-<br/><br/><a name="library_S"></a><h2>S </h2>
-<a href="lib.Sets.html">Sets</a> <br/>
-<a href="backend.Stacking.html">Stacking</a> <br/>
-<a href="backend.Stackingproof.html">Stackingproof</a> <br/>
-<a href="backend.Stackingtyping.html">Stackingtyping</a> <br/>
-<br/><br/><a name="library_T"></a><h2>T </h2>
-<a href="backend.Tunneling.html">Tunneling</a> <br/>
-<a href="backend.Tunnelingproof.html">Tunnelingproof</a> <br/>
-<a href="backend.Tunnelingtyping.html">Tunnelingtyping</a> <br/>
-<br/><br/><a name="library_U"></a><h2>U </h2>
-<a href="lib.union_find.html">union_find</a> <br/>
-<br/><br/><a name="library_V"></a><h2>V </h2>
-<a href="backend.Values.html">Values</a> <br/>
-<br/><br/><hr/><table>
-<tr>
-<td>Global Index</td>
-<td><a href="index.html#global_A">A</a></td>
-<td><a href="index.html#global_B">B</a></td>
-<td><a href="index.html#global_C">C</a></td>
-<td><a href="index.html#global_D">D</a></td>
-<td><a href="index.html#global_E">E</a></td>
-<td><a href="index.html#global_F">F</a></td>
-<td><a href="index.html#global_G">G</a></td>
-<td><a href="index.html#global_H">H</a></td>
-<td><a href="index.html#global_I">I</a></td>
-<td>J</td>
-<td><a href="index.html#global_K">K</a></td>
-<td><a href="index.html#global_L">L</a></td>
-<td><a href="index.html#global_M">M</a></td>
-<td><a href="index.html#global_N">N</a></td>
-<td><a href="index.html#global_O">O</a></td>
-<td><a href="index.html#global_P">P</a></td>
-<td>Q</td>
-<td><a href="index.html#global_R">R</a></td>
-<td><a href="index.html#global_S">S</a></td>
-<td><a href="index.html#global_T">T</a></td>
-<td><a href="index.html#global_U">U</a></td>
-<td><a href="index.html#global_V">V</a></td>
-<td><a href="index.html#global_W">W</a></td>
-<td><a href="index.html#global_X">X</a></td>
-<td>Y</td>
-<td><a href="index.html#global_Z">Z</a></td>
-<td><a href="index.html#global__">_</a></td>
-<td>(3806 entries)</td>
-</tr>
-<tr>
-<td>Axiom Index</td>
-<td><a href="index.html#axiom_A">A</a></td>
-<td>B</td>
-<td><a href="index.html#axiom_C">C</a></td>
-<td><a href="index.html#axiom_D">D</a></td>
-<td><a href="index.html#axiom_E">E</a></td>
-<td><a href="index.html#axiom_F">F</a></td>
-<td><a href="index.html#axiom_G">G</a></td>
-<td><a href="index.html#axiom_H">H</a></td>
-<td><a href="index.html#axiom_I">I</a></td>
-<td>J</td>
-<td>K</td>
-<td><a href="index.html#axiom_L">L</a></td>
-<td><a href="index.html#axiom_M">M</a></td>
-<td><a href="index.html#axiom_N">N</a></td>
-<td><a href="index.html#axiom_O">O</a></td>
-<td><a href="index.html#axiom_P">P</a></td>
-<td>Q</td>
-<td>R</td>
-<td><a href="index.html#axiom_S">S</a></td>
-<td>T</td>
-<td>U</td>
-<td>V</td>
-<td>W</td>
-<td>X</td>
-<td>Y</td>
-<td><a href="index.html#axiom_Z">Z</a></td>
-<td>_</td>
-<td>(39 entries)</td>
-</tr>
-<tr>
-<td>Lemma Index</td>
-<td><a href="index.html#lemma_A">A</a></td>
-<td><a href="index.html#lemma_B">B</a></td>
-<td><a href="index.html#lemma_C">C</a></td>
-<td><a href="index.html#lemma_D">D</a></td>
-<td><a href="index.html#lemma_E">E</a></td>
-<td><a href="index.html#lemma_F">F</a></td>
-<td><a href="index.html#lemma_G">G</a></td>
-<td><a href="index.html#lemma_H">H</a></td>
-<td><a href="index.html#lemma_I">I</a></td>
-<td>J</td>
-<td><a href="index.html#lemma_K">K</a></td>
-<td><a href="index.html#lemma_L">L</a></td>
-<td><a href="index.html#lemma_M">M</a></td>
-<td><a href="index.html#lemma_N">N</a></td>
-<td><a href="index.html#lemma_O">O</a></td>
-<td><a href="index.html#lemma_P">P</a></td>
-<td>Q</td>
-<td><a href="index.html#lemma_R">R</a></td>
-<td><a href="index.html#lemma_S">S</a></td>
-<td><a href="index.html#lemma_T">T</a></td>
-<td><a href="index.html#lemma_U">U</a></td>
-<td><a href="index.html#lemma_V">V</a></td>
-<td><a href="index.html#lemma_W">W</a></td>
-<td><a href="index.html#lemma_X">X</a></td>
-<td>Y</td>
-<td><a href="index.html#lemma_Z">Z</a></td>
-<td>_</td>
-<td>(1753 entries)</td>
-</tr>
-<tr>
-<td>Constructor Index</td>
-<td><a href="index.html#constructor_A">A</a></td>
-<td><a href="index.html#constructor_B">B</a></td>
-<td><a href="index.html#constructor_C">C</a></td>
-<td><a href="index.html#constructor_D">D</a></td>
-<td><a href="index.html#constructor_E">E</a></td>
-<td><a href="index.html#constructor_F">F</a></td>
-<td><a href="index.html#constructor_G">G</a></td>
-<td>H</td>
-<td><a href="index.html#constructor_I">I</a></td>
-<td>J</td>
-<td>K</td>
-<td><a href="index.html#constructor_L">L</a></td>
-<td><a href="index.html#constructor_M">M</a></td>
-<td><a href="index.html#constructor_N">N</a></td>
-<td><a href="index.html#constructor_O">O</a></td>
-<td><a href="index.html#constructor_P">P</a></td>
-<td>Q</td>
-<td><a href="index.html#constructor_R">R</a></td>
-<td><a href="index.html#constructor_S">S</a></td>
-<td><a href="index.html#constructor_T">T</a></td>
-<td><a href="index.html#constructor_U">U</a></td>
-<td><a href="index.html#constructor_V">V</a></td>
-<td><a href="index.html#constructor_W">W</a></td>
-<td>X</td>
-<td>Y</td>
-<td>Z</td>
-<td><a href="index.html#constructor__">_</a></td>
-<td>(700 entries)</td>
-</tr>
-<tr>
-<td>Inductive Index</td>
-<td><a href="index.html#inductive_A">A</a></td>
-<td><a href="index.html#inductive_B">B</a></td>
-<td><a href="index.html#inductive_C">C</a></td>
-<td><a href="index.html#inductive_D">D</a></td>
-<td><a href="index.html#inductive_E">E</a></td>
-<td><a href="index.html#inductive_F">F</a></td>
-<td><a href="index.html#inductive_G">G</a></td>
-<td>H</td>
-<td><a href="index.html#inductive_I">I</a></td>
-<td>J</td>
-<td>K</td>
-<td><a href="index.html#inductive_L">L</a></td>
-<td><a href="index.html#inductive_M">M</a></td>
-<td><a href="index.html#inductive_N">N</a></td>
-<td><a href="index.html#inductive_O">O</a></td>
-<td><a href="index.html#inductive_P">P</a></td>
-<td>Q</td>
-<td><a href="index.html#inductive_R">R</a></td>
-<td><a href="index.html#inductive_S">S</a></td>
-<td><a href="index.html#inductive_T">T</a></td>
-<td><a href="index.html#inductive_U">U</a></td>
-<td><a href="index.html#inductive_V">V</a></td>
-<td><a href="index.html#inductive_W">W</a></td>
-<td>X</td>
-<td>Y</td>
-<td>Z</td>
-<td>_</td>
-<td>(155 entries)</td>
-</tr>
-<tr>
-<td>Definition Index</td>
-<td><a href="index.html#definition_A">A</a></td>
-<td><a href="index.html#definition_B">B</a></td>
-<td><a href="index.html#definition_C">C</a></td>
-<td><a href="index.html#definition_D">D</a></td>
-<td><a href="index.html#definition_E">E</a></td>
-<td><a href="index.html#definition_F">F</a></td>
-<td><a href="index.html#definition_G">G</a></td>
-<td><a href="index.html#definition_H">H</a></td>
-<td><a href="index.html#definition_I">I</a></td>
-<td>J</td>
-<td><a href="index.html#definition_K">K</a></td>
-<td><a href="index.html#definition_L">L</a></td>
-<td><a href="index.html#definition_M">M</a></td>
-<td><a href="index.html#definition_N">N</a></td>
-<td><a href="index.html#definition_O">O</a></td>
-<td><a href="index.html#definition_P">P</a></td>
-<td>Q</td>
-<td><a href="index.html#definition_R">R</a></td>
-<td><a href="index.html#definition_S">S</a></td>
-<td><a href="index.html#definition_T">T</a></td>
-<td><a href="index.html#definition_U">U</a></td>
-<td><a href="index.html#definition_V">V</a></td>
-<td><a href="index.html#definition_W">W</a></td>
-<td><a href="index.html#definition_X">X</a></td>
-<td>Y</td>
-<td><a href="index.html#definition_Z">Z</a></td>
-<td>_</td>
-<td>(1017 entries)</td>
-</tr>
-<tr>
-<td>Module Index</td>
-<td><a href="index.html#module_A">A</a></td>
-<td><a href="index.html#module_B">B</a></td>
-<td>C</td>
-<td><a href="index.html#module_D">D</a></td>
-<td><a href="index.html#module_E">E</a></td>
-<td><a href="index.html#module_F">F</a></td>
-<td><a href="index.html#module_G">G</a></td>
-<td>H</td>
-<td><a href="index.html#module_I">I</a></td>
-<td>J</td>
-<td>K</td>
-<td><a href="index.html#module_L">L</a></td>
-<td><a href="index.html#module_M">M</a></td>
-<td><a href="index.html#module_N">N</a></td>
-<td><a href="index.html#module_O">O</a></td>
-<td><a href="index.html#module_P">P</a></td>
-<td>Q</td>
-<td><a href="index.html#module_R">R</a></td>
-<td><a href="index.html#module_S">S</a></td>
-<td><a href="index.html#module_T">T</a></td>
-<td><a href="index.html#module_U">U</a></td>
-<td><a href="index.html#module_V">V</a></td>
-<td>W</td>
-<td>X</td>
-<td>Y</td>
-<td><a href="index.html#module_Z">Z</a></td>
-<td>_</td>
-<td>(78 entries)</td>
-</tr>
-<tr>
-<td>Library Index</td>
-<td><a href="index.html#library_A">A</a></td>
-<td>B</td>
-<td><a href="index.html#library_C">C</a></td>
-<td>D</td>
-<td>E</td>
-<td><a href="index.html#library_F">F</a></td>
-<td><a href="index.html#library_G">G</a></td>
-<td>H</td>
-<td><a href="index.html#library_I">I</a></td>
-<td>J</td>
-<td><a href="index.html#library_K">K</a></td>
-<td><a href="index.html#library_L">L</a></td>
-<td><a href="index.html#library_M">M</a></td>
-<td>N</td>
-<td><a href="index.html#library_O">O</a></td>
-<td><a href="index.html#library_P">P</a></td>
-<td>Q</td>
-<td><a href="index.html#library_R">R</a></td>
-<td><a href="index.html#library_S">S</a></td>
-<td><a href="index.html#library_T">T</a></td>
-<td><a href="index.html#library_U">U</a></td>
-<td><a href="index.html#library_V">V</a></td>
-<td>W</td>
-<td>X</td>
-<td>Y</td>
-<td>Z</td>
-<td>_</td>
-<td>(64 entries)</td>
-</tr>
-</table>
-<hr/><font size="-1">This page has been generated by <a href="http://www.lri.fr/~filliatr/coqdoc/">coqdoc</a></font>
-</body>
-</html> \ No newline at end of file
+<LINK type="text/css" rel="stylesheet" href="style.css">
+</HEAD>
+<BODY>
+
+<H1 align="center">The Compcert certified compiler back-end</H1>
+<H2 align="center">Commented Coq development</H2>
+<H3 align="center">Version 0.2, 2006-01-07</H3>
+
+<H2>Introduction</H2>
+
+<P>The Compcert back-end is a compiler that generates PowerPC assembly
+code from a low-level intermediate language called Cminor and a
+slightly more expressive intermediate language called Csharpminor.
+The particularity of this compiler is that it is written mostly within
+the specification language of the Coq proof assistant, and its
+correctness --- the fact that the generated assembly code is
+semantically equivalent to its source program --- was entirely proved
+within the Coq proof assistant.</P>
+
+<P>A high-level overview of the Compcert back-end and its proof of
+correctness can be found in the following paper:</P>
+<CITE>Xavier Leroy, <A
+HREF="http://pauillac.inria.fr/~xleroy/publi/compiler-certif.pdf">Formal
+certification of a compiler back-end, or: programming a compiler with
+a proof assistant</A>. Proceedings of the POPL 2006 symposium.</CITE>
+
+<P>This Web site gives a commented listing of the underlying Coq
+specifications and proofs. Proof scripts and the parts of the
+compiler written directly in Caml are omitted. This development is a
+work in progress; some parts may have changed since the overview paper
+above was written.</P>
+
+<P>This document and all Coq source files referenced from it are
+copyright 2005, 2006 Institut National de Recherche en Informatique et
+en Automatique (INRIA) and distributed under the terms of the <A
+HREF="http://www.gnu.org/licenses/gpl.html">GNU General Public
+License</A> version 2.</P>
+
+<H2>Table of contents</H2>
+
+<H3>General-purpose libraries, data structures and algorithms</H3>
+
+<UL>
+<LI> <A HREF="html/Coqlib.html">Coqlib</A>: addendum to the Coq standard library.
+ (Coq source file with proofs:
+ <A HREF="Coqlib.v"><code>Coqlib.v</code></a>.)
+<LI> <A HREF="html/Maps.html">Maps</A>: finite maps.
+ (Coq source file with proofs:
+ <A HREF="Maps.v"><code>Maps.v</code></a>.)
+<LI> <A HREF="html/Integers.html">Integers</A>: machine integers.
+ (Coq source file with proofs:
+ <A HREF="Integers.v"><code>Integers.v</code></a>.)
+<LI> <A HREF="html/Floats.html">Floats</A>: machine floating-point numbers.
+<LI> <A HREF="html/Iteration.html">Iteration</A>: various forms of "while" loops.
+<LI> <A HREF="html/Ordered.html">Ordered</A>: construction of
+ordered types.
+<LI> <A HREF="html/Lattice.html">Lattice</A>: construction of
+semi-lattices.
+<LI> <A HREF="html/Kildall.html">Kildall</A>: resolution of dataflow
+inequations by fixpoint iteration.
+<LI> <A HREF="html/Parmov.html">Parmov</A>: compilation of parallel assignments.
+</UL>
+
+<H3>Definitions and properties used in many parts of the development</H3>
+
+<UL>
+<LI> <A HREF="html/Errors.html">Errors</A>: the Error monad.
+<LI> <A HREF="html/AST.html">AST</A>: identifiers, whole programs and other
+common elements of abstract syntaxes.
+ (Coq source file with proofs: <A HREF="AST.v"><code>AST.v</code></a>.)
+<LI> <A HREF="html/Values.html">Values</A>: run-time values.
+<LI> <A HREF="html/Events.html">Events</A>: observable events and traces.
+<LI> <A HREF="html/Mem.html">Mem</A>: the memory model.
+<LI> <A HREF="html/Globalenvs.html">Globalenvs</A>: global execution environments.
+<LI> <A HREF="html/Smallstep.html">Smallstep</A>: tools for small-step semantics.
+<LI> <A HREF="html/Op.html">Op</A>: operators, addressing modes and their
+semantics.
+</UL>
+
+<H3>Source, intermediate and target languages: syntax and semantics</H3>
+
+<UL>
+<!--
+ <LI> <A HREF="html/Csharpminor.html">Csharpminor</A>: low-level structured language.
+-->
+<LI> <A HREF="html/Cminor.html">Cminor</A>: low-level structured
+language, with explicit stack allocation of certain local variables.
+<LI> <A HREF="html/CminorSel.html">CminorSel</A>: like Cminor,
+with machine-specific operators and addressing modes.
+<LI> <A HREF="html/RTL.html">RTL</A>: register transfer language (3-address
+code, control-flow graph, infinitely many pseudo-registers). <BR>
+See also: <A HREF="html/Registers.html">Registers</A> (representation of
+pseudo-registers).
+<LI> <A HREF="html/LTL.html">LTL</A>: location transfer language (3-address
+code, control-flow graph, finitely many physical registers, infinitely
+many stack slots). <BR>
+See also: <A HREF="html/Locations.html">Locations</A> (representation of
+locations).
+<LI> <A HREF="html/LTL.html">LTLin</A>: like LTL, but the CFG is
+replaced by a linear list of instructions with explicit branches and labels.
+<LI> <A HREF="html/Linear.html">Linear</A>: like LTLin, with explicit
+spilling, reloading and enforcement of calling conventions.
+<LI> <A HREF="html/Mach.html">Mach</A>: like Linear, with a more concrete
+view of the activation record. <BR>
+See also: <A HREF="html/Machabstr.html">Machabstr</A> abstract semantics for Mach. <BR>
+See also: <A HREF="html/Machconcr.html">Machconcr</A> concrete semantics for Mach.
+<LI> <A HREF="html/PPC.html">PPC</A>: abstract syntax for PowerPC assembly
+code.
+</UL>
+
+<H3>Compiler passes</H3>
+
+<TABLE cellpadding="5%">
+<TR valign="top">
+ <TH>Pass</TH>
+ <TH>Source &amp; target</TH>
+ <TH>Compiler&nbsp;code</TH>
+ <TH>Correctness&nbsp;proof</TH>
+</TR>
+
+<!--
+<TR valign="top">
+ <TD>Stack allocation of local variables<br>whose address is taken</TD>
+ <TD>Csharpminor to Cminor</TD>
+ <TD><A HREF="html/Cminorgen.html">Cminorgen</A></TD>
+ <TD><A HREF="html/Cminorgenproof.html">Cminorgenproof</A></TD>
+</TR>
+-->
+
+<TR valign="top">
+ <TD>Recognition of operators<br>and addressing modes</TD>
+ <TD>Cminor to CminorSel</TD>
+ <TD><A HREF="html/Selection.html">Selection</A></TD>
+ <TD><A HREF="html/Selectionproof.html">Selectionproof</A></TD>
+</TR>
+
+<TR valign="top">
+ <TD>Construction of the CFG, <br>3-address code generation</TD>
+ <TD>Cminor to RTL</TD>
+ <TD><A HREF="html/RTLgen.html">RTLgen</A></TD>
+ <TD><A HREF="html/RTLgenspec.html">RTLgenspec</A><BR>
+ <A HREF="html/RTLgenproof.html">RTLgenproof</A></TD>
+</TR>
+
+<TR valign="top">
+ <TD>Constant propagation</TD>
+ <TD>RTL to RTL</TD>
+ <TD><A HREF="html/Constprop.html">Constprop</A></TD>
+ <TD><A HREF="html/Constpropproof.html">Constpropproof</A></TD>
+</TR>
+
+<TR valign="top">
+ <TD>Common subexpression elimination</TD>
+ <TD>RTL to RTL</TD>
+ <TD><A HREF="html/CSE.html">CSE</A></TD>
+ <TD><A HREF="html/CSEproof.html">CSEproof</A></TD>
+</TR>
+
+<TR valign="top">
+ <TD>Register allocation by coloring<br>of an interference graph</TD>
+ <TD>RTL to LTL</TD>
+ <TD><A HREF="html/InterfGraph.html">InterfGraph</A><BR>
+ <A HREF="html/Coloring.html">Coloring</A><BR>
+ <A HREF="html/Allocation.html">Allocation</A></TD>
+ <TD><BR>
+ <A HREF="html/Coloringproof.html">Coloringproof</A><BR>
+ <A HREF="html/Allocproof.html">Allocproof</A></TD>
+</TR>
+
+<TR valign="top">
+ <TD>Branch tunneling</TD>
+ <TD>LTL to LTL</TD>
+ <TD><A HREF="html/Tunneling.html">Tunneling</A></TD>
+ <TD><A HREF="html/Tunnelingproof.html">Tunnelingproof</A></TD>
+</TR>
+
+<TR valign="top">
+ <TD>Linearization of the CFG</TD>
+ <TD>LTL to LTLin</TD>
+ <TD><A HREF="html/Linearize.html">Linearize</A></TD>
+ <TD><A HREF="html/Linearizeproof.html">Linearizeproof</A></TD>
+</TR>
+
+<TR valign="top">
+ <TD>Spilling, reloading, calling conventions</TD>
+ <TD>LTLin to Linear</TD>
+ <TD><A HREF="html/Conventions.html">Conventions</A><BR>
+ <A HREF="html/Reload.html">Reload</A></TD>
+ <TD><A HREF="html/Parallelmove.html">Parallelmove</A><BR>
+ <A HREF="html/Reloadproof.html">Reloadproof</A></TD>
+</TR>
+
+<TR valign="top">
+ <TD>Laying out the activation records</TD>
+ <TD>Linear to Mach</TD>
+ <TD><A HREF="html/Bounds.html">Bounds</A><BR>
+ <A HREF="html/Stacking.html">Stacking</A></TD>
+ <TD><A HREF="html/Stackingproof.html">Stackingproof</A></TD>
+</TR>
+
+<TR valign="top">
+ <TD>Storing the activation records in memory</TD>
+ <TD>Mach to Mach</TD>
+ <TD>(none)
+ <TD><A HREF="html/PPCgenretaddr.html">PPCgenretaddr</A><BR>
+ <A HREF="html/Machabstr2mach.html">Machabstr2mach</A></TD>
+
+<TR valign="top">
+ <TD>Emission of PowerPC assembly</TD>
+ <TD>Mach to PPC</TD>
+ <TD><A HREF="html/PPCgen.html">PPCgen</A></TD>
+ <TD><A HREF="html/PPCgenproof1.html">PPCgenproof1</A><BR>
+ <A HREF="html/PPCgenproof.html">PPCgenproof</A></TD>
+</TR>
+</TABLE>
+
+<H3>Type systems</H3>
+
+Trivial type systems are used to statically capture well-formedness
+conditions on the intermediate languages.
+<UL>
+<LI> <A HREF="html/RTLtyping.html">RTLtyping</A>: typing for RTL + type
+reconstruction.
+<LI> <A HREF="html/LTLtyping.html">LTLtyping</A>: typing for LTL.
+<LI> <A HREF="html/LTLintyping.html">LTLintyping</A>: typing for LTLin.
+<LI> <A HREF="html/Lineartyping.html">Lineartyping</A>: typing for Linear.
+<LI> <A HREF="html/Machtyping.html">Machtyping</A>: typing for Mach.
+</UL>
+Proofs that compiler passes are type-preserving:
+<UL>
+<LI> <A HREF="html/Alloctyping.html">Alloctyping</A> (register allocation).
+<LI> <A HREF="html/Tunnelingtyping.html">Tunnelingtyping</A> (branch tunneling).
+<LI> <A HREF="html/Linearizetyping.html">Linearizetyping</A> (code linearization).
+<LI> <A HREF="html/Reloadtyping.html">Reloadtyping</A> (spilling and reloading).
+<LI> <A HREF="html/Stackingtyping.html">Stackingtyping</A> (layout of activation records).
+</UL>
+
+<H3>All together</H3>
+
+<UL>
+<LI> <A HREF="html/Main.html">Main</A>: composing the passes together; the
+final semantic preservation theorems.
+</UL>
+
+<HR>
+<ADDRESS>Xavier.Leroy@inria.fr</ADDRESS>
+<HR>
+
+</BODY>
+</HTML>
diff --git a/doc/removeproofs b/doc/removeproofs
index 0ebe3a8..82809ba 100755
--- a/doc/removeproofs
+++ b/doc/removeproofs
@@ -2,7 +2,7 @@
for i in $*; do
mv $i $i.bak
- sed -e '/<code class="keyword">Proof<\/code>\./,/<code class="keyword">Qed<\/code>\./d' $i.bak > $i
+ sed -e '/<code class="keyword">Proof<\/code> *\./,/<code class="keyword">\(Qed\|Defined\)<\/code> *\./d' $i.bak > $i
rm $i.bak
done
diff --git a/doc/style.css b/doc/style.css
index 9c1eb49..dced2ff 100644
--- a/doc/style.css
+++ b/doc/style.css
@@ -26,7 +26,9 @@ tr { background-color : White }
# .doc { background-color :#66ff66 }
.doc { margin-left: -5%; }
.docright { margin-left: 40%; }
-h1 { margin-left: -10%; text-align: right; }
+div.doc code { color : #008000; font-weight: bold }
+h1.libtitle { text-align: center; }
+h1 { margin-left: -5%; }
h2 { margin-left: -5%; }
h3,h4,h5,h6 { margin-left: -3%; }
hr { margin-left: -10%; margin-right:-10%; }
diff --git a/extraction/.depend b/extraction/.depend
index 53f8468..956c4d3 100644
--- a/extraction/.depend
+++ b/extraction/.depend
@@ -8,20 +8,20 @@
../caml/CMlexer.cmi
../caml/CMlexer.cmx: ../caml/Camlcoq.cmx ../caml/CMparser.cmx \
../caml/CMlexer.cmi
-../caml/CMparser.cmo: Op.cmi Integers.cmi Datatypes.cmi Cminor.cmi \
- Cmconstr.cmi ../caml/Camlcoq.cmo CList.cmi BinPos.cmi BinInt.cmi AST.cmi \
+../caml/CMparser.cmo: Integers.cmi Datatypes.cmi Cminor.cmi \
+ ../caml/Camlcoq.cmo CList.cmi BinPos.cmi BinInt.cmi AST.cmi \
../caml/CMparser.cmi
-../caml/CMparser.cmx: Op.cmx Integers.cmx Datatypes.cmx Cminor.cmx \
- Cmconstr.cmx ../caml/Camlcoq.cmx CList.cmx BinPos.cmx BinInt.cmx AST.cmx \
+../caml/CMparser.cmx: Integers.cmx Datatypes.cmx Cminor.cmx \
+ ../caml/Camlcoq.cmx CList.cmx BinPos.cmx BinInt.cmx AST.cmx \
../caml/CMparser.cmi
../caml/CMtypecheck.cmo: Op.cmi Integers.cmi Datatypes.cmi Cminor.cmi \
../caml/Camlcoq.cmo CList.cmi AST.cmi ../caml/CMtypecheck.cmi
../caml/CMtypecheck.cmx: Op.cmx Integers.cmx Datatypes.cmx Cminor.cmx \
../caml/Camlcoq.cmx CList.cmx AST.cmx ../caml/CMtypecheck.cmi
-../caml/Camlcoq.cmo: Integers.cmi Datatypes.cmi CList.cmi BinPos.cmi \
- BinInt.cmi
-../caml/Camlcoq.cmx: Integers.cmx Datatypes.cmx CList.cmx BinPos.cmx \
- BinInt.cmx
+../caml/Camlcoq.cmo: Integers.cmi Datatypes.cmi CString.cmi CList.cmi \
+ BinPos.cmi BinInt.cmi Ascii.cmi
+../caml/Camlcoq.cmx: Integers.cmx Datatypes.cmx CString.cmx CList.cmx \
+ BinPos.cmx BinInt.cmx Ascii.cmx
../caml/Cil2Csyntax.cmo: Datatypes.cmi Csyntax.cmi ../caml/Camlcoq.cmo \
CList.cmi AST.cmi
../caml/Cil2Csyntax.cmx: Datatypes.cmx Csyntax.cmx ../caml/Camlcoq.cmx \
@@ -35,15 +35,11 @@
../caml/Floataux.cmo: Integers.cmi ../caml/Camlcoq.cmo
../caml/Floataux.cmx: Integers.cmx ../caml/Camlcoq.cmx
../caml/Main2.cmo: ../caml/PrintPPC.cmi ../caml/PrintCsyntax.cmo Main.cmi \
- Datatypes.cmi Csyntax.cmi ../caml/Cil2Csyntax.cmo ../caml/CMtypecheck.cmi \
+ Errors.cmi Csyntax.cmi ../caml/Cil2Csyntax.cmo ../caml/CMtypecheck.cmi \
../caml/CMparser.cmi ../caml/CMlexer.cmi
../caml/Main2.cmx: ../caml/PrintPPC.cmx ../caml/PrintCsyntax.cmx Main.cmx \
- Datatypes.cmx Csyntax.cmx ../caml/Cil2Csyntax.cmx ../caml/CMtypecheck.cmx \
+ Errors.cmx Csyntax.cmx ../caml/Cil2Csyntax.cmx ../caml/CMtypecheck.cmx \
../caml/CMparser.cmx ../caml/CMlexer.cmx
-../caml/PrintCshm.cmo: Integers.cmi Datatypes.cmi Csharpminor.cmi \
- ../caml/Camlcoq.cmo CList.cmi AST.cmi
-../caml/PrintCshm.cmx: Integers.cmx Datatypes.cmx Csharpminor.cmx \
- ../caml/Camlcoq.cmx CList.cmx AST.cmx
../caml/PrintCsyntax.cmo: Datatypes.cmi Csyntax.cmi ../caml/Camlcoq.cmo \
CList.cmi AST.cmi
../caml/PrintCsyntax.cmx: Datatypes.cmx Csyntax.cmx ../caml/Camlcoq.cmx \
@@ -52,32 +48,40 @@
AST.cmi ../caml/PrintPPC.cmi
../caml/PrintPPC.cmx: PPC.cmx Datatypes.cmx ../caml/Camlcoq.cmx CList.cmx \
AST.cmx ../caml/PrintPPC.cmi
-../caml/RTLgenaux.cmo: Cminor.cmi
-../caml/RTLgenaux.cmx: Cminor.cmx
+../caml/RTLgenaux.cmo: Switch.cmi Integers.cmi Datatypes.cmi CminorSel.cmi \
+ CList.cmi
+../caml/RTLgenaux.cmx: Switch.cmx Integers.cmx Datatypes.cmx CminorSel.cmx \
+ CList.cmx
../caml/RTLtypingaux.cmo: Registers.cmi RTL.cmi Op.cmi Maps.cmi Datatypes.cmi \
../caml/Camlcoq.cmo CList.cmi AST.cmi
../caml/RTLtypingaux.cmx: Registers.cmx RTL.cmx Op.cmx Maps.cmx Datatypes.cmx \
../caml/Camlcoq.cmx CList.cmx AST.cmx
-AST.cmi: Specif.cmi Integers.cmi Floats.cmi Datatypes.cmi Coqlib.cmi \
- CList.cmi BinPos.cmi BinInt.cmi
-Allocation.cmi: Specif.cmi Registers.cmi RTLtyping.cmi RTL.cmi \
- Parallelmove.cmi Op.cmi Maps.cmi Locations.cmi LTL.cmi Datatypes.cmi \
- Conventions.cmi Coloring.cmi CList.cmi BinPos.cmi AST.cmi
+AST.cmi: Specif.cmi Integers.cmi Floats.cmi Errors.cmi Datatypes.cmi \
+ Coqlib.cmi CString.cmi CList.cmi BinPos.cmi BinInt.cmi Ascii.cmi
+Allocation.cmi: Specif.cmi Registers.cmi RTLtyping.cmi RTL.cmi Op.cmi \
+ Maps.cmi Locations.cmi LTL.cmi Errors.cmi Datatypes.cmi Coloring.cmi \
+ CString.cmi CList.cmi BinPos.cmi Ascii.cmi AST.cmi
+Ascii.cmi: Specif.cmi Peano.cmi Datatypes.cmi Bool.cmi BinPos.cmi
BinInt.cmi: Datatypes.cmi BinPos.cmi BinNat.cmi
BinNat.cmi: Specif.cmi Datatypes.cmi BinPos.cmi
BinPos.cmi: Peano.cmi Datatypes.cmi
Bool.cmi: Specif.cmi Datatypes.cmi
+Bounds.cmi: Zmax.cmi Locations.cmi Linear.cmi Conventions.cmi CList.cmi \
+ BinPos.cmi BinInt.cmi AST.cmi
CInt.cmi: Zmax.cmi ZArith_dec.cmi Specif.cmi BinPos.cmi BinInt.cmi
CList.cmi: Specif.cmi Datatypes.cmi
CSE.cmi: Specif.cmi Registers.cmi RTL.cmi Op.cmi Maps.cmi Integers.cmi \
Floats.cmi Datatypes.cmi Coqlib.cmi CList.cmi BinPos.cmi AST.cmi
-Cmconstr.cmi: Specif.cmi Op.cmi Integers.cmi Datatypes.cmi Compare_dec.cmi \
- Cminor.cmi CList.cmi BinPos.cmi BinInt.cmi AST.cmi
-Cminor.cmi: Values.cmi Op.cmi Maps.cmi Integers.cmi Globalenvs.cmi \
- Datatypes.cmi CList.cmi BinInt.cmi AST.cmi
-Cminorgen.cmi: Zmax.cmi Specif.cmi OrderedType.cmi Ordered.cmi Op.cmi Mem.cmi \
- Maps.cmi Integers.cmi Datatypes.cmi Csharpminor.cmi Coqlib.cmi Cminor.cmi \
- Cmconstr.cmi CList.cmi CInt.cmi BinPos.cmi BinInt.cmi AST.cmi
+CString.cmi: Specif.cmi Datatypes.cmi Ascii.cmi
+Cminor.cmi: Values.cmi Specif.cmi Mem.cmi Maps.cmi Integers.cmi \
+ Globalenvs.cmi Floats.cmi Datatypes.cmi CList.cmi BinPos.cmi BinInt.cmi \
+ AST.cmi
+CminorSel.cmi: Op.cmi Integers.cmi Globalenvs.cmi Datatypes.cmi CList.cmi \
+ BinInt.cmi AST.cmi
+Cminorgen.cmi: Zmax.cmi Specif.cmi OrderedType.cmi Ordered.cmi Mem.cmi \
+ Maps.cmi Integers.cmi Errors.cmi Datatypes.cmi Csharpminor.cmi Coqlib.cmi \
+ Cminor.cmi CString.cmi CList.cmi CInt.cmi BinPos.cmi BinInt.cmi Ascii.cmi \
+ AST.cmi
Coloring.cmi: Specif.cmi Registers.cmi RTLtyping.cmi RTL.cmi Op.cmi Maps.cmi \
Locations.cmi InterfGraph.cmi Datatypes.cmi Coqlib.cmi Conventions.cmi \
CList.cmi BinInt.cmi AST.cmi
@@ -88,15 +92,19 @@ Conventions.cmi: Locations.cmi Datatypes.cmi Coqlib.cmi CList.cmi BinPos.cmi \
BinInt.cmi AST.cmi
Coqlib.cmi: Zdiv.cmi ZArith_dec.cmi Wf.cmi Specif.cmi Datatypes.cmi CList.cmi \
BinPos.cmi BinInt.cmi
-Csharpminor.cmi: Zmax.cmi Values.cmi Specif.cmi Mem.cmi Maps.cmi Integers.cmi \
- Globalenvs.cmi Floats.cmi Datatypes.cmi CList.cmi BinPos.cmi BinInt.cmi \
+Csharpminor.cmi: Zmax.cmi Values.cmi Mem.cmi Maps.cmi Integers.cmi \
+ Globalenvs.cmi Floats.cmi Datatypes.cmi Cminor.cmi CList.cmi BinInt.cmi \
AST.cmi
-Cshmgen.cmi: Peano.cmi Integers.cmi Floats.cmi Datatypes.cmi Csyntax.cmi \
- Csharpminor.cmi CList.cmi AST.cmi
-Csyntax.cmi: Zmax.cmi Specif.cmi Integers.cmi Floats.cmi Datatypes.cmi \
- Coqlib.cmi CList.cmi BinPos.cmi BinInt.cmi AST.cmi
+Cshmgen.cmi: Peano.cmi Integers.cmi Floats.cmi Errors.cmi Datatypes.cmi \
+ Csyntax.cmi Csharpminor.cmi Cminor.cmi CString.cmi CList.cmi Ascii.cmi \
+ AST.cmi
+Csyntax.cmi: Zmax.cmi Specif.cmi Integers.cmi Floats.cmi Errors.cmi \
+ Datatypes.cmi Coqlib.cmi CString.cmi CList.cmi BinPos.cmi BinInt.cmi \
+ Ascii.cmi AST.cmi
Ctyping.cmi: Specif.cmi Maps.cmi Datatypes.cmi Csyntax.cmi Coqlib.cmi \
CList.cmi AST.cmi
+EqNat.cmi: Specif.cmi Datatypes.cmi
+Errors.cmi: Datatypes.cmi CString.cmi CList.cmi BinPos.cmi
FSetAVL.cmi: Wf.cmi Specif.cmi Peano.cmi OrderedType.cmi Datatypes.cmi \
CList.cmi CInt.cmi BinPos.cmi BinInt.cmi
FSetFacts.cmi: Specif.cmi Setoid.cmi FSetInterface.cmi Datatypes.cmi
@@ -110,34 +118,36 @@ Integers.cmi: Zpower.cmi Zdiv.cmi Specif.cmi Datatypes.cmi Coqlib.cmi \
InterfGraph.cmi: Specif.cmi Registers.cmi OrderedType.cmi Locations.cmi \
Datatypes.cmi Coqlib.cmi CList.cmi CInt.cmi BinPos.cmi BinInt.cmi
Iteration.cmi: Wf.cmi Specif.cmi Datatypes.cmi Coqlib.cmi BinPos.cmi
-Kildall.cmi: Specif.cmi Setoid.cmi OrderedType.cmi Maps.cmi Lattice.cmi \
- Iteration.cmi Datatypes.cmi Coqlib.cmi CList.cmi CInt.cmi BinPos.cmi \
- BinInt.cmi
-LTL.cmi: Values.cmi Specif.cmi Op.cmi Maps.cmi Locations.cmi Integers.cmi \
- Globalenvs.cmi Datatypes.cmi Conventions.cmi CList.cmi BinPos.cmi \
- BinInt.cmi AST.cmi
+Kildall.cmi: Specif.cmi Setoid.cmi OrderedType.cmi Ordered.cmi Maps.cmi \
+ Lattice.cmi Iteration.cmi Datatypes.cmi Coqlib.cmi CList.cmi CInt.cmi \
+ BinPos.cmi BinInt.cmi
+LTL.cmi: Values.cmi Specif.cmi Op.cmi Mem.cmi Maps.cmi Locations.cmi \
+ Integers.cmi Globalenvs.cmi Datatypes.cmi Conventions.cmi CList.cmi \
+ BinPos.cmi BinInt.cmi AST.cmi
+LTLin.cmi: Values.cmi Specif.cmi Op.cmi Mem.cmi Locations.cmi Integers.cmi \
+ Globalenvs.cmi Datatypes.cmi Coqlib.cmi CList.cmi BinPos.cmi BinInt.cmi \
+ AST.cmi
Lattice.cmi: Specif.cmi Maps.cmi FSetInterface.cmi Datatypes.cmi Bool.cmi \
BinPos.cmi
-Linear.cmi: Values.cmi Specif.cmi Op.cmi Locations.cmi Integers.cmi \
+Linear.cmi: Values.cmi Specif.cmi Op.cmi Mem.cmi Locations.cmi Integers.cmi \
Globalenvs.cmi Datatypes.cmi Coqlib.cmi CList.cmi BinPos.cmi BinInt.cmi \
AST.cmi
-Linearize.cmi: Specif.cmi Op.cmi Maps.cmi Linear.cmi Lattice.cmi LTL.cmi \
+Linearize.cmi: Specif.cmi Op.cmi Maps.cmi Lattice.cmi LTLin.cmi LTL.cmi \
Datatypes.cmi Coqlib.cmi CList.cmi BinPos.cmi AST.cmi
-Lineartyping.cmi: Zmax.cmi Locations.cmi Linear.cmi Datatypes.cmi \
- Conventions.cmi CList.cmi BinPos.cmi BinInt.cmi AST.cmi
Locations.cmi: Values.cmi Specif.cmi Datatypes.cmi Coqlib.cmi BinPos.cmi \
BinInt.cmi AST.cmi
-Mach.cmi: Zmax.cmi Zdiv.cmi Values.cmi Specif.cmi Op.cmi Mem.cmi \
- Locations.cmi Integers.cmi Globalenvs.cmi Datatypes.cmi Coqlib.cmi \
- CList.cmi BinPos.cmi BinInt.cmi AST.cmi
-Main.cmi: Tunneling.cmi Stacking.cmi RTLgen.cmi PPCgen.cmi PPC.cmi \
- Linearize.cmi Datatypes.cmi Ctyping.cmi Csyntax.cmi Cshmgen.cmi \
- Constprop.cmi Cminorgen.cmi Cminor.cmi CSE.cmi Allocation.cmi AST.cmi
+Mach.cmi: Zmax.cmi Zdiv.cmi Values.cmi Specif.cmi Op.cmi Locations.cmi \
+ Integers.cmi Globalenvs.cmi Datatypes.cmi Coqlib.cmi CList.cmi BinPos.cmi \
+ BinInt.cmi AST.cmi
+Main.cmi: Tunneling.cmi Stacking.cmi Selection.cmi Reload.cmi RTLgen.cmi \
+ RTL.cmi PPCgen.cmi PPC.cmi Linearize.cmi Errors.cmi Datatypes.cmi \
+ Ctyping.cmi Csyntax.cmi Cshmgen.cmi Constprop.cmi Cminorgen.cmi \
+ Cminor.cmi CString.cmi CSE.cmi Ascii.cmi Allocation.cmi AST.cmi
Maps.cmi: Specif.cmi Datatypes.cmi Coqlib.cmi CList.cmi BinPos.cmi BinNat.cmi \
BinInt.cmi
Mem.cmi: Zmax.cmi Values.cmi Specif.cmi Integers.cmi Datatypes.cmi Coqlib.cmi \
CList.cmi BinPos.cmi BinInt.cmi AST.cmi
-Op.cmi: Values.cmi Specif.cmi Integers.cmi Globalenvs.cmi Floats.cmi \
+Op.cmi: Values.cmi Specif.cmi Mem.cmi Integers.cmi Globalenvs.cmi Floats.cmi \
Datatypes.cmi CList.cmi Bool.cmi BinPos.cmi BinInt.cmi AST.cmi
Ordered.cmi: Specif.cmi OrderedType.cmi Maps.cmi Datatypes.cmi Coqlib.cmi \
BinPos.cmi
@@ -145,24 +155,32 @@ OrderedType.cmi: Specif.cmi Datatypes.cmi
PPC.cmi: Values.cmi Specif.cmi Mem.cmi Integers.cmi Globalenvs.cmi Floats.cmi \
Datatypes.cmi Coqlib.cmi CList.cmi BinPos.cmi BinInt.cmi AST.cmi
PPCgen.cmi: Specif.cmi PPC.cmi Op.cmi Mach.cmi Locations.cmi Integers.cmi \
- Datatypes.cmi Coqlib.cmi CList.cmi Bool.cmi BinPos.cmi BinInt.cmi AST.cmi
+ Errors.cmi Datatypes.cmi Coqlib.cmi CString.cmi CList.cmi Bool.cmi \
+ BinPos.cmi BinInt.cmi Ascii.cmi AST.cmi
Parallelmove.cmi: Parmov.cmi Locations.cmi Datatypes.cmi CList.cmi AST.cmi
Parmov.cmi: Specif.cmi Peano.cmi Datatypes.cmi CList.cmi
Peano.cmi: Datatypes.cmi
-RTL.cmi: Values.cmi Registers.cmi Op.cmi Maps.cmi Integers.cmi Globalenvs.cmi \
- Datatypes.cmi CList.cmi BinPos.cmi BinInt.cmi AST.cmi
-RTLgen.cmi: Specif.cmi Registers.cmi RTL.cmi Op.cmi Maps.cmi Integers.cmi \
- Datatypes.cmi Coqlib.cmi Cminor.cmi CList.cmi BinPos.cmi AST.cmi
-RTLtyping.cmi: Specif.cmi Registers.cmi RTL.cmi Op.cmi Maps.cmi Datatypes.cmi \
- Coqlib.cmi CList.cmi AST.cmi
+RTL.cmi: Values.cmi Registers.cmi Op.cmi Mem.cmi Maps.cmi Integers.cmi \
+ Globalenvs.cmi Datatypes.cmi CList.cmi BinPos.cmi BinInt.cmi AST.cmi
+RTLgen.cmi: Switch.cmi Specif.cmi Registers.cmi RTL.cmi Op.cmi Maps.cmi \
+ Integers.cmi Errors.cmi Datatypes.cmi Coqlib.cmi CminorSel.cmi \
+ CString.cmi CList.cmi BinPos.cmi Ascii.cmi AST.cmi
+RTLtyping.cmi: Specif.cmi Registers.cmi RTL.cmi Op.cmi Maps.cmi Errors.cmi \
+ Datatypes.cmi Coqlib.cmi Conventions.cmi CString.cmi CList.cmi BinPos.cmi \
+ BinInt.cmi Ascii.cmi AST.cmi
Registers.cmi: Specif.cmi OrderedType.cmi Ordered.cmi Maps.cmi Datatypes.cmi \
Coqlib.cmi CList.cmi CInt.cmi BinPos.cmi BinInt.cmi AST.cmi
+Reload.cmi: Specif.cmi Parallelmove.cmi Op.cmi Locations.cmi Linear.cmi \
+ LTLin.cmi Datatypes.cmi Conventions.cmi CList.cmi AST.cmi
+Selection.cmi: Specif.cmi Op.cmi Integers.cmi Datatypes.cmi Compare_dec.cmi \
+ CminorSel.cmi Cminor.cmi CList.cmi BinPos.cmi BinInt.cmi AST.cmi
Setoid.cmi: Datatypes.cmi
Specif.cmi: Datatypes.cmi
-Stacking.cmi: Specif.cmi Op.cmi Mach.cmi Locations.cmi Lineartyping.cmi \
- Linear.cmi Integers.cmi Datatypes.cmi Coqlib.cmi Conventions.cmi \
- CList.cmi BinPos.cmi BinInt.cmi AST.cmi
+Stacking.cmi: Specif.cmi Op.cmi Mach.cmi Locations.cmi Linear.cmi \
+ Integers.cmi Errors.cmi Datatypes.cmi Coqlib.cmi Conventions.cmi \
+ CString.cmi CList.cmi Bounds.cmi BinPos.cmi BinInt.cmi Ascii.cmi AST.cmi
Sumbool.cmi: Specif.cmi Datatypes.cmi
+Switch.cmi: Integers.cmi EqNat.cmi Datatypes.cmi CList.cmi
Tunneling.cmi: Maps.cmi LTL.cmi Datatypes.cmi AST.cmi
Values.cmi: Specif.cmi Integers.cmi Floats.cmi Datatypes.cmi Coqlib.cmi \
BinPos.cmi BinInt.cmi AST.cmi
@@ -175,18 +193,20 @@ Zeven.cmi: Specif.cmi Datatypes.cmi BinPos.cmi BinInt.cmi
Zmax.cmi: Datatypes.cmi BinInt.cmi
Zmisc.cmi: Datatypes.cmi BinPos.cmi BinInt.cmi
Zpower.cmi: Zmisc.cmi Datatypes.cmi BinPos.cmi BinInt.cmi
-AST.cmo: Specif.cmi Integers.cmi Floats.cmi Datatypes.cmi Coqlib.cmi \
- CList.cmi BinPos.cmi BinInt.cmi AST.cmi
-AST.cmx: Specif.cmx Integers.cmx Floats.cmx Datatypes.cmx Coqlib.cmx \
- CList.cmx BinPos.cmx BinInt.cmx AST.cmi
-Allocation.cmo: Specif.cmi Registers.cmi RTLtyping.cmi RTL.cmi \
- Parallelmove.cmi Op.cmi Maps.cmi Locations.cmi Lattice.cmi LTL.cmi \
- Kildall.cmi Datatypes.cmi Conventions.cmi Coloring.cmi CList.cmi \
- BinPos.cmi AST.cmi Allocation.cmi
-Allocation.cmx: Specif.cmx Registers.cmx RTLtyping.cmx RTL.cmx \
- Parallelmove.cmx Op.cmx Maps.cmx Locations.cmx Lattice.cmx LTL.cmx \
- Kildall.cmx Datatypes.cmx Conventions.cmx Coloring.cmx CList.cmx \
- BinPos.cmx AST.cmx Allocation.cmi
+AST.cmo: Specif.cmi Integers.cmi Floats.cmi Errors.cmi Datatypes.cmi \
+ Coqlib.cmi CString.cmi CList.cmi BinPos.cmi BinInt.cmi Ascii.cmi AST.cmi
+AST.cmx: Specif.cmx Integers.cmx Floats.cmx Errors.cmx Datatypes.cmx \
+ Coqlib.cmx CString.cmx CList.cmx BinPos.cmx BinInt.cmx Ascii.cmx AST.cmi
+Allocation.cmo: Specif.cmi Registers.cmi RTLtyping.cmi RTL.cmi Op.cmi \
+ Maps.cmi Locations.cmi Lattice.cmi LTL.cmi Kildall.cmi Errors.cmi \
+ Datatypes.cmi Coloring.cmi CString.cmi CList.cmi BinPos.cmi Ascii.cmi \
+ AST.cmi Allocation.cmi
+Allocation.cmx: Specif.cmx Registers.cmx RTLtyping.cmx RTL.cmx Op.cmx \
+ Maps.cmx Locations.cmx Lattice.cmx LTL.cmx Kildall.cmx Errors.cmx \
+ Datatypes.cmx Coloring.cmx CString.cmx CList.cmx BinPos.cmx Ascii.cmx \
+ AST.cmx Allocation.cmi
+Ascii.cmo: Specif.cmi Peano.cmi Datatypes.cmi Bool.cmi BinPos.cmi Ascii.cmi
+Ascii.cmx: Specif.cmx Peano.cmx Datatypes.cmx Bool.cmx BinPos.cmx Ascii.cmi
BinInt.cmo: Datatypes.cmi BinPos.cmi BinNat.cmi BinInt.cmi
BinInt.cmx: Datatypes.cmx BinPos.cmx BinNat.cmx BinInt.cmi
BinNat.cmo: Specif.cmi Datatypes.cmi BinPos.cmi BinNat.cmi
@@ -195,6 +215,10 @@ BinPos.cmo: Peano.cmi Datatypes.cmi BinPos.cmi
BinPos.cmx: Peano.cmx Datatypes.cmx BinPos.cmi
Bool.cmo: Specif.cmi Datatypes.cmi Bool.cmi
Bool.cmx: Specif.cmx Datatypes.cmx Bool.cmi
+Bounds.cmo: Zmax.cmi Locations.cmi Linear.cmi Conventions.cmi CList.cmi \
+ BinPos.cmi BinInt.cmi AST.cmi Bounds.cmi
+Bounds.cmx: Zmax.cmx Locations.cmx Linear.cmx Conventions.cmx CList.cmx \
+ BinPos.cmx BinInt.cmx AST.cmx Bounds.cmi
CInt.cmo: Zmax.cmi ZArith_dec.cmi Specif.cmi BinPos.cmi BinInt.cmi CInt.cmi
CInt.cmx: Zmax.cmx ZArith_dec.cmx Specif.cmx BinPos.cmx BinInt.cmx CInt.cmi
CList.cmo: Specif.cmi Datatypes.cmi CList.cmi
@@ -205,22 +229,26 @@ CSE.cmo: Specif.cmi Registers.cmi RTL.cmi Op.cmi Maps.cmi Kildall.cmi \
CSE.cmx: Specif.cmx Registers.cmx RTL.cmx Op.cmx Maps.cmx Kildall.cmx \
Integers.cmx Floats.cmx Datatypes.cmx Coqlib.cmx CList.cmx BinPos.cmx \
AST.cmx CSE.cmi
-Cmconstr.cmo: Specif.cmi Op.cmi Integers.cmi Datatypes.cmi Compare_dec.cmi \
- Cminor.cmi CList.cmi BinPos.cmi BinInt.cmi AST.cmi Cmconstr.cmi
-Cmconstr.cmx: Specif.cmx Op.cmx Integers.cmx Datatypes.cmx Compare_dec.cmx \
- Cminor.cmx CList.cmx BinPos.cmx BinInt.cmx AST.cmx Cmconstr.cmi
-Cminor.cmo: Values.cmi Op.cmi Maps.cmi Integers.cmi Globalenvs.cmi \
- Datatypes.cmi CList.cmi BinInt.cmi AST.cmi Cminor.cmi
-Cminor.cmx: Values.cmx Op.cmx Maps.cmx Integers.cmx Globalenvs.cmx \
- Datatypes.cmx CList.cmx BinInt.cmx AST.cmx Cminor.cmi
-Cminorgen.cmo: Zmax.cmi Specif.cmi OrderedType.cmi Ordered.cmi Op.cmi Mem.cmi \
- Maps.cmi Integers.cmi FSetAVL.cmi Datatypes.cmi Csharpminor.cmi \
- Coqlib.cmi Cminor.cmi Cmconstr.cmi CList.cmi BinPos.cmi BinInt.cmi \
- AST.cmi Cminorgen.cmi
-Cminorgen.cmx: Zmax.cmx Specif.cmx OrderedType.cmx Ordered.cmx Op.cmx Mem.cmx \
- Maps.cmx Integers.cmx FSetAVL.cmx Datatypes.cmx Csharpminor.cmx \
- Coqlib.cmx Cminor.cmx Cmconstr.cmx CList.cmx BinPos.cmx BinInt.cmx \
- AST.cmx Cminorgen.cmi
+CString.cmo: Specif.cmi Datatypes.cmi Ascii.cmi CString.cmi
+CString.cmx: Specif.cmx Datatypes.cmx Ascii.cmx CString.cmi
+Cminor.cmo: Values.cmi Specif.cmi Mem.cmi Maps.cmi Integers.cmi \
+ Globalenvs.cmi Floats.cmi Datatypes.cmi CList.cmi BinPos.cmi BinInt.cmi \
+ AST.cmi Cminor.cmi
+Cminor.cmx: Values.cmx Specif.cmx Mem.cmx Maps.cmx Integers.cmx \
+ Globalenvs.cmx Floats.cmx Datatypes.cmx CList.cmx BinPos.cmx BinInt.cmx \
+ AST.cmx Cminor.cmi
+CminorSel.cmo: Op.cmi Integers.cmi Globalenvs.cmi Datatypes.cmi CList.cmi \
+ BinInt.cmi AST.cmi CminorSel.cmi
+CminorSel.cmx: Op.cmx Integers.cmx Globalenvs.cmx Datatypes.cmx CList.cmx \
+ BinInt.cmx AST.cmx CminorSel.cmi
+Cminorgen.cmo: Zmax.cmi Specif.cmi OrderedType.cmi Ordered.cmi Mem.cmi \
+ Maps.cmi Integers.cmi FSetAVL.cmi Errors.cmi Datatypes.cmi \
+ Csharpminor.cmi Coqlib.cmi Cminor.cmi CString.cmi CList.cmi BinPos.cmi \
+ BinInt.cmi Ascii.cmi AST.cmi Cminorgen.cmi
+Cminorgen.cmx: Zmax.cmx Specif.cmx OrderedType.cmx Ordered.cmx Mem.cmx \
+ Maps.cmx Integers.cmx FSetAVL.cmx Errors.cmx Datatypes.cmx \
+ Csharpminor.cmx Coqlib.cmx Cminor.cmx CString.cmx CList.cmx BinPos.cmx \
+ BinInt.cmx Ascii.cmx AST.cmx Cminorgen.cmi
Coloring.cmo: Specif.cmi Registers.cmi RTLtyping.cmi RTL.cmi Op.cmi Maps.cmi \
Locations.cmi InterfGraph.cmi Datatypes.cmi Coqlib.cmi Conventions.cmi \
../caml/Coloringaux.cmi CList.cmi BinInt.cmi AST.cmi Coloring.cmi
@@ -243,26 +271,34 @@ Coqlib.cmo: Zdiv.cmi ZArith_dec.cmi Wf.cmi Specif.cmi Datatypes.cmi CList.cmi \
BinPos.cmi BinInt.cmi Coqlib.cmi
Coqlib.cmx: Zdiv.cmx ZArith_dec.cmx Wf.cmx Specif.cmx Datatypes.cmx CList.cmx \
BinPos.cmx BinInt.cmx Coqlib.cmi
-Csharpminor.cmo: Zmax.cmi Values.cmi Specif.cmi Mem.cmi Maps.cmi Integers.cmi \
- Globalenvs.cmi Floats.cmi Datatypes.cmi CList.cmi BinPos.cmi BinInt.cmi \
+Csharpminor.cmo: Zmax.cmi Values.cmi Mem.cmi Maps.cmi Integers.cmi \
+ Globalenvs.cmi Floats.cmi Datatypes.cmi Cminor.cmi CList.cmi BinInt.cmi \
AST.cmi Csharpminor.cmi
-Csharpminor.cmx: Zmax.cmx Values.cmx Specif.cmx Mem.cmx Maps.cmx Integers.cmx \
- Globalenvs.cmx Floats.cmx Datatypes.cmx CList.cmx BinPos.cmx BinInt.cmx \
+Csharpminor.cmx: Zmax.cmx Values.cmx Mem.cmx Maps.cmx Integers.cmx \
+ Globalenvs.cmx Floats.cmx Datatypes.cmx Cminor.cmx CList.cmx BinInt.cmx \
AST.cmx Csharpminor.cmi
-Cshmgen.cmo: Peano.cmi Integers.cmi Floats.cmi Datatypes.cmi Csyntax.cmi \
- Csharpminor.cmi CList.cmi AST.cmi Cshmgen.cmi
-Cshmgen.cmx: Peano.cmx Integers.cmx Floats.cmx Datatypes.cmx Csyntax.cmx \
- Csharpminor.cmx CList.cmx AST.cmx Cshmgen.cmi
-Csyntax.cmo: Zmax.cmi Specif.cmi Integers.cmi Floats.cmi Datatypes.cmi \
- Coqlib.cmi CList.cmi BinPos.cmi BinInt.cmi AST.cmi Csyntax.cmi
-Csyntax.cmx: Zmax.cmx Specif.cmx Integers.cmx Floats.cmx Datatypes.cmx \
- Coqlib.cmx CList.cmx BinPos.cmx BinInt.cmx AST.cmx Csyntax.cmi
+Cshmgen.cmo: Peano.cmi Integers.cmi Floats.cmi Errors.cmi Datatypes.cmi \
+ Csyntax.cmi Csharpminor.cmi Cminor.cmi CString.cmi CList.cmi Ascii.cmi \
+ AST.cmi Cshmgen.cmi
+Cshmgen.cmx: Peano.cmx Integers.cmx Floats.cmx Errors.cmx Datatypes.cmx \
+ Csyntax.cmx Csharpminor.cmx Cminor.cmx CString.cmx CList.cmx Ascii.cmx \
+ AST.cmx Cshmgen.cmi
+Csyntax.cmo: Zmax.cmi Specif.cmi Integers.cmi Floats.cmi Errors.cmi \
+ Datatypes.cmi Coqlib.cmi CString.cmi CList.cmi BinPos.cmi BinInt.cmi \
+ Ascii.cmi AST.cmi Csyntax.cmi
+Csyntax.cmx: Zmax.cmx Specif.cmx Integers.cmx Floats.cmx Errors.cmx \
+ Datatypes.cmx Coqlib.cmx CString.cmx CList.cmx BinPos.cmx BinInt.cmx \
+ Ascii.cmx AST.cmx Csyntax.cmi
Ctyping.cmo: Specif.cmi Maps.cmi Datatypes.cmi Csyntax.cmi Coqlib.cmi \
CList.cmi AST.cmi Ctyping.cmi
Ctyping.cmx: Specif.cmx Maps.cmx Datatypes.cmx Csyntax.cmx Coqlib.cmx \
CList.cmx AST.cmx Ctyping.cmi
Datatypes.cmo: Datatypes.cmi
Datatypes.cmx: Datatypes.cmi
+EqNat.cmo: Specif.cmi Datatypes.cmi EqNat.cmi
+EqNat.cmx: Specif.cmx Datatypes.cmx EqNat.cmi
+Errors.cmo: Datatypes.cmi CString.cmi CList.cmi BinPos.cmi Errors.cmi
+Errors.cmx: Datatypes.cmx CString.cmx CList.cmx BinPos.cmx Errors.cmi
FSetAVL.cmo: Wf.cmi Specif.cmi Peano.cmi OrderedType.cmi FSetList.cmi \
Datatypes.cmi CList.cmi CInt.cmi BinPos.cmi BinInt.cmi FSetAVL.cmi
FSetAVL.cmx: Wf.cmx Specif.cmx Peano.cmx OrderedType.cmx FSetList.cmx \
@@ -299,58 +335,60 @@ Iteration.cmo: Wf.cmi Specif.cmi Datatypes.cmi Coqlib.cmi BinPos.cmi \
Iteration.cmi
Iteration.cmx: Wf.cmx Specif.cmx Datatypes.cmx Coqlib.cmx BinPos.cmx \
Iteration.cmi
-Kildall.cmo: Specif.cmi Setoid.cmi OrderedType.cmi Maps.cmi Lattice.cmi \
- Iteration.cmi FSetFacts.cmi FSetAVL.cmi Datatypes.cmi Coqlib.cmi \
- CList.cmi BinPos.cmi BinInt.cmi Kildall.cmi
-Kildall.cmx: Specif.cmx Setoid.cmx OrderedType.cmx Maps.cmx Lattice.cmx \
- Iteration.cmx FSetFacts.cmx FSetAVL.cmx Datatypes.cmx Coqlib.cmx \
- CList.cmx BinPos.cmx BinInt.cmx Kildall.cmi
-LTL.cmo: Values.cmi Specif.cmi Op.cmi Maps.cmi Locations.cmi Integers.cmi \
- Globalenvs.cmi Datatypes.cmi Conventions.cmi CList.cmi BinPos.cmi \
- BinInt.cmi AST.cmi LTL.cmi
-LTL.cmx: Values.cmx Specif.cmx Op.cmx Maps.cmx Locations.cmx Integers.cmx \
- Globalenvs.cmx Datatypes.cmx Conventions.cmx CList.cmx BinPos.cmx \
- BinInt.cmx AST.cmx LTL.cmi
+Kildall.cmo: Specif.cmi Setoid.cmi OrderedType.cmi Ordered.cmi Maps.cmi \
+ Lattice.cmi Iteration.cmi FSetFacts.cmi FSetAVL.cmi Datatypes.cmi \
+ Coqlib.cmi CList.cmi BinPos.cmi BinInt.cmi Kildall.cmi
+Kildall.cmx: Specif.cmx Setoid.cmx OrderedType.cmx Ordered.cmx Maps.cmx \
+ Lattice.cmx Iteration.cmx FSetFacts.cmx FSetAVL.cmx Datatypes.cmx \
+ Coqlib.cmx CList.cmx BinPos.cmx BinInt.cmx Kildall.cmi
+LTL.cmo: Values.cmi Specif.cmi Op.cmi Mem.cmi Maps.cmi Locations.cmi \
+ Integers.cmi Globalenvs.cmi Datatypes.cmi Conventions.cmi CList.cmi \
+ BinPos.cmi BinInt.cmi AST.cmi LTL.cmi
+LTL.cmx: Values.cmx Specif.cmx Op.cmx Mem.cmx Maps.cmx Locations.cmx \
+ Integers.cmx Globalenvs.cmx Datatypes.cmx Conventions.cmx CList.cmx \
+ BinPos.cmx BinInt.cmx AST.cmx LTL.cmi
+LTLin.cmo: Values.cmi Specif.cmi Op.cmi Mem.cmi Locations.cmi Integers.cmi \
+ Globalenvs.cmi Datatypes.cmi Coqlib.cmi CList.cmi BinPos.cmi BinInt.cmi \
+ AST.cmi LTLin.cmi
+LTLin.cmx: Values.cmx Specif.cmx Op.cmx Mem.cmx Locations.cmx Integers.cmx \
+ Globalenvs.cmx Datatypes.cmx Coqlib.cmx CList.cmx BinPos.cmx BinInt.cmx \
+ AST.cmx LTLin.cmi
Lattice.cmo: Specif.cmi Maps.cmi FSetInterface.cmi Datatypes.cmi Bool.cmi \
BinPos.cmi Lattice.cmi
Lattice.cmx: Specif.cmx Maps.cmx FSetInterface.cmx Datatypes.cmx Bool.cmx \
BinPos.cmx Lattice.cmi
-Linear.cmo: Values.cmi Specif.cmi Op.cmi Locations.cmi Integers.cmi \
+Linear.cmo: Values.cmi Specif.cmi Op.cmi Mem.cmi Locations.cmi Integers.cmi \
Globalenvs.cmi Datatypes.cmi Coqlib.cmi CList.cmi BinPos.cmi BinInt.cmi \
AST.cmi Linear.cmi
-Linear.cmx: Values.cmx Specif.cmx Op.cmx Locations.cmx Integers.cmx \
+Linear.cmx: Values.cmx Specif.cmx Op.cmx Mem.cmx Locations.cmx Integers.cmx \
Globalenvs.cmx Datatypes.cmx Coqlib.cmx CList.cmx BinPos.cmx BinInt.cmx \
AST.cmx Linear.cmi
-Linearize.cmo: Specif.cmi Op.cmi Maps.cmi Linear.cmi Lattice.cmi LTL.cmi \
+Linearize.cmo: Specif.cmi Op.cmi Maps.cmi Lattice.cmi LTLin.cmi LTL.cmi \
Kildall.cmi Datatypes.cmi Coqlib.cmi CList.cmi BinPos.cmi AST.cmi \
Linearize.cmi
-Linearize.cmx: Specif.cmx Op.cmx Maps.cmx Linear.cmx Lattice.cmx LTL.cmx \
+Linearize.cmx: Specif.cmx Op.cmx Maps.cmx Lattice.cmx LTLin.cmx LTL.cmx \
Kildall.cmx Datatypes.cmx Coqlib.cmx CList.cmx BinPos.cmx AST.cmx \
Linearize.cmi
-Lineartyping.cmo: Zmax.cmi Locations.cmi Linear.cmi Datatypes.cmi \
- Conventions.cmi CList.cmi BinPos.cmi BinInt.cmi AST.cmi Lineartyping.cmi
-Lineartyping.cmx: Zmax.cmx Locations.cmx Linear.cmx Datatypes.cmx \
- Conventions.cmx CList.cmx BinPos.cmx BinInt.cmx AST.cmx Lineartyping.cmi
Locations.cmo: Values.cmi Specif.cmi Datatypes.cmi Coqlib.cmi BinPos.cmi \
BinInt.cmi AST.cmi Locations.cmi
Locations.cmx: Values.cmx Specif.cmx Datatypes.cmx Coqlib.cmx BinPos.cmx \
BinInt.cmx AST.cmx Locations.cmi
Logic.cmo: Logic.cmi
Logic.cmx: Logic.cmi
-Mach.cmo: Zmax.cmi Zdiv.cmi Values.cmi Specif.cmi Op.cmi Mem.cmi Maps.cmi \
+Mach.cmo: Zmax.cmi Zdiv.cmi Values.cmi Specif.cmi Op.cmi Maps.cmi \
Locations.cmi Integers.cmi Globalenvs.cmi Datatypes.cmi Coqlib.cmi \
CList.cmi BinPos.cmi BinInt.cmi AST.cmi Mach.cmi
-Mach.cmx: Zmax.cmx Zdiv.cmx Values.cmx Specif.cmx Op.cmx Mem.cmx Maps.cmx \
+Mach.cmx: Zmax.cmx Zdiv.cmx Values.cmx Specif.cmx Op.cmx Maps.cmx \
Locations.cmx Integers.cmx Globalenvs.cmx Datatypes.cmx Coqlib.cmx \
CList.cmx BinPos.cmx BinInt.cmx AST.cmx Mach.cmi
-Main.cmo: Tunneling.cmi Stacking.cmi RTLgen.cmi PPCgen.cmi PPC.cmi \
- Linearize.cmi Datatypes.cmi Ctyping.cmi Csyntax.cmi Cshmgen.cmi \
- Constprop.cmi Cminorgen.cmi Cminor.cmi CSE.cmi Allocation.cmi AST.cmi \
- Main.cmi
-Main.cmx: Tunneling.cmx Stacking.cmx RTLgen.cmx PPCgen.cmx PPC.cmx \
- Linearize.cmx Datatypes.cmx Ctyping.cmx Csyntax.cmx Cshmgen.cmx \
- Constprop.cmx Cminorgen.cmx Cminor.cmx CSE.cmx Allocation.cmx AST.cmx \
- Main.cmi
+Main.cmo: Tunneling.cmi Stacking.cmi Selection.cmi Reload.cmi RTLgen.cmi \
+ RTL.cmi PPCgen.cmi PPC.cmi Linearize.cmi Errors.cmi Datatypes.cmi \
+ Ctyping.cmi Csyntax.cmi Cshmgen.cmi Constprop.cmi Cminorgen.cmi \
+ Cminor.cmi CString.cmi CSE.cmi Ascii.cmi Allocation.cmi AST.cmi Main.cmi
+Main.cmx: Tunneling.cmx Stacking.cmx Selection.cmx Reload.cmx RTLgen.cmx \
+ RTL.cmx PPCgen.cmx PPC.cmx Linearize.cmx Errors.cmx Datatypes.cmx \
+ Ctyping.cmx Csyntax.cmx Cshmgen.cmx Constprop.cmx Cminorgen.cmx \
+ Cminor.cmx CString.cmx CSE.cmx Ascii.cmx Allocation.cmx AST.cmx Main.cmi
Maps.cmo: Specif.cmi Datatypes.cmi Coqlib.cmi CList.cmi BinPos.cmi BinNat.cmi \
BinInt.cmi Maps.cmi
Maps.cmx: Specif.cmx Datatypes.cmx Coqlib.cmx CList.cmx BinPos.cmx BinNat.cmx \
@@ -359,9 +397,9 @@ Mem.cmo: Zmax.cmi Values.cmi Specif.cmi Integers.cmi Datatypes.cmi Coqlib.cmi \
CList.cmi BinPos.cmi BinInt.cmi AST.cmi Mem.cmi
Mem.cmx: Zmax.cmx Values.cmx Specif.cmx Integers.cmx Datatypes.cmx Coqlib.cmx \
CList.cmx BinPos.cmx BinInt.cmx AST.cmx Mem.cmi
-Op.cmo: Values.cmi Specif.cmi Integers.cmi Globalenvs.cmi Floats.cmi \
+Op.cmo: Values.cmi Specif.cmi Mem.cmi Integers.cmi Globalenvs.cmi Floats.cmi \
Datatypes.cmi CList.cmi Bool.cmi BinPos.cmi BinInt.cmi AST.cmi Op.cmi
-Op.cmx: Values.cmx Specif.cmx Integers.cmx Globalenvs.cmx Floats.cmx \
+Op.cmx: Values.cmx Specif.cmx Mem.cmx Integers.cmx Globalenvs.cmx Floats.cmx \
Datatypes.cmx CList.cmx Bool.cmx BinPos.cmx BinInt.cmx AST.cmx Op.cmi
Ordered.cmo: Specif.cmi OrderedType.cmi Maps.cmi Datatypes.cmi Coqlib.cmi \
BinPos.cmi Ordered.cmi
@@ -376,11 +414,11 @@ PPC.cmx: Values.cmx Specif.cmx Mem.cmx Maps.cmx Integers.cmx Globalenvs.cmx \
Floats.cmx Datatypes.cmx Coqlib.cmx CList.cmx BinPos.cmx BinInt.cmx \
AST.cmx PPC.cmi
PPCgen.cmo: Specif.cmi PPC.cmi Op.cmi Mach.cmi Locations.cmi Integers.cmi \
- Datatypes.cmi Coqlib.cmi CList.cmi Bool.cmi BinPos.cmi BinInt.cmi AST.cmi \
- PPCgen.cmi
+ Errors.cmi Datatypes.cmi Coqlib.cmi CString.cmi CList.cmi Bool.cmi \
+ BinPos.cmi BinInt.cmi Ascii.cmi AST.cmi PPCgen.cmi
PPCgen.cmx: Specif.cmx PPC.cmx Op.cmx Mach.cmx Locations.cmx Integers.cmx \
- Datatypes.cmx Coqlib.cmx CList.cmx Bool.cmx BinPos.cmx BinInt.cmx AST.cmx \
- PPCgen.cmi
+ Errors.cmx Datatypes.cmx Coqlib.cmx CString.cmx CList.cmx Bool.cmx \
+ BinPos.cmx BinInt.cmx Ascii.cmx AST.cmx PPCgen.cmi
Parallelmove.cmo: Parmov.cmi Locations.cmi Datatypes.cmi CList.cmi AST.cmi \
Parallelmove.cmi
Parallelmove.cmx: Parmov.cmx Locations.cmx Datatypes.cmx CList.cmx AST.cmx \
@@ -389,38 +427,60 @@ Parmov.cmo: Specif.cmi Peano.cmi Datatypes.cmi CList.cmi Parmov.cmi
Parmov.cmx: Specif.cmx Peano.cmx Datatypes.cmx CList.cmx Parmov.cmi
Peano.cmo: Datatypes.cmi Peano.cmi
Peano.cmx: Datatypes.cmx Peano.cmi
-RTL.cmo: Values.cmi Registers.cmi Op.cmi Maps.cmi Integers.cmi Globalenvs.cmi \
- Datatypes.cmi CList.cmi BinPos.cmi BinInt.cmi AST.cmi RTL.cmi
-RTL.cmx: Values.cmx Registers.cmx Op.cmx Maps.cmx Integers.cmx Globalenvs.cmx \
- Datatypes.cmx CList.cmx BinPos.cmx BinInt.cmx AST.cmx RTL.cmi
-RTLgen.cmo: Specif.cmi Registers.cmi ../caml/RTLgenaux.cmo RTL.cmi Op.cmi \
- Maps.cmi Integers.cmi Datatypes.cmi Coqlib.cmi Cminor.cmi CList.cmi \
- BinPos.cmi AST.cmi RTLgen.cmi
-RTLgen.cmx: Specif.cmx Registers.cmx ../caml/RTLgenaux.cmx RTL.cmx Op.cmx \
- Maps.cmx Integers.cmx Datatypes.cmx Coqlib.cmx Cminor.cmx CList.cmx \
- BinPos.cmx AST.cmx RTLgen.cmi
+RTL.cmo: Values.cmi Registers.cmi Op.cmi Mem.cmi Maps.cmi Integers.cmi \
+ Globalenvs.cmi Datatypes.cmi CList.cmi BinPos.cmi BinInt.cmi AST.cmi \
+ RTL.cmi
+RTL.cmx: Values.cmx Registers.cmx Op.cmx Mem.cmx Maps.cmx Integers.cmx \
+ Globalenvs.cmx Datatypes.cmx CList.cmx BinPos.cmx BinInt.cmx AST.cmx \
+ RTL.cmi
+RTLgen.cmo: Switch.cmi Specif.cmi Registers.cmi ../caml/RTLgenaux.cmo RTL.cmi \
+ Op.cmi Maps.cmi Integers.cmi Errors.cmi Datatypes.cmi Coqlib.cmi \
+ CminorSel.cmi CString.cmi CList.cmi BinPos.cmi Ascii.cmi AST.cmi \
+ RTLgen.cmi
+RTLgen.cmx: Switch.cmx Specif.cmx Registers.cmx ../caml/RTLgenaux.cmx RTL.cmx \
+ Op.cmx Maps.cmx Integers.cmx Errors.cmx Datatypes.cmx Coqlib.cmx \
+ CminorSel.cmx CString.cmx CList.cmx BinPos.cmx Ascii.cmx AST.cmx \
+ RTLgen.cmi
RTLtyping.cmo: Specif.cmi Registers.cmi ../caml/RTLtypingaux.cmo RTL.cmi \
- Op.cmi Maps.cmi Datatypes.cmi Coqlib.cmi CList.cmi AST.cmi RTLtyping.cmi
+ Op.cmi Maps.cmi Errors.cmi Datatypes.cmi Coqlib.cmi Conventions.cmi \
+ CString.cmi CList.cmi BinPos.cmi BinInt.cmi Ascii.cmi AST.cmi \
+ RTLtyping.cmi
RTLtyping.cmx: Specif.cmx Registers.cmx ../caml/RTLtypingaux.cmx RTL.cmx \
- Op.cmx Maps.cmx Datatypes.cmx Coqlib.cmx CList.cmx AST.cmx RTLtyping.cmi
+ Op.cmx Maps.cmx Errors.cmx Datatypes.cmx Coqlib.cmx Conventions.cmx \
+ CString.cmx CList.cmx BinPos.cmx BinInt.cmx Ascii.cmx AST.cmx \
+ RTLtyping.cmi
Registers.cmo: Specif.cmi OrderedType.cmi Ordered.cmi Maps.cmi FSetAVL.cmi \
Datatypes.cmi Coqlib.cmi CList.cmi BinPos.cmi BinInt.cmi AST.cmi \
Registers.cmi
Registers.cmx: Specif.cmx OrderedType.cmx Ordered.cmx Maps.cmx FSetAVL.cmx \
Datatypes.cmx Coqlib.cmx CList.cmx BinPos.cmx BinInt.cmx AST.cmx \
Registers.cmi
+Reload.cmo: Specif.cmi Parallelmove.cmi Op.cmi Locations.cmi Linear.cmi \
+ LTLin.cmi Datatypes.cmi Conventions.cmi CList.cmi AST.cmi Reload.cmi
+Reload.cmx: Specif.cmx Parallelmove.cmx Op.cmx Locations.cmx Linear.cmx \
+ LTLin.cmx Datatypes.cmx Conventions.cmx CList.cmx AST.cmx Reload.cmi
+Selection.cmo: Specif.cmi Op.cmi Integers.cmi Datatypes.cmi Compare_dec.cmi \
+ CminorSel.cmi Cminor.cmi CList.cmi BinPos.cmi BinInt.cmi AST.cmi \
+ Selection.cmi
+Selection.cmx: Specif.cmx Op.cmx Integers.cmx Datatypes.cmx Compare_dec.cmx \
+ CminorSel.cmx Cminor.cmx CList.cmx BinPos.cmx BinInt.cmx AST.cmx \
+ Selection.cmi
Setoid.cmo: Datatypes.cmi Setoid.cmi
Setoid.cmx: Datatypes.cmx Setoid.cmi
Specif.cmo: Datatypes.cmi Specif.cmi
Specif.cmx: Datatypes.cmx Specif.cmi
-Stacking.cmo: Specif.cmi Op.cmi Mach.cmi Locations.cmi Lineartyping.cmi \
- Linear.cmi Integers.cmi Datatypes.cmi Coqlib.cmi Conventions.cmi \
- CList.cmi BinPos.cmi BinInt.cmi AST.cmi Stacking.cmi
-Stacking.cmx: Specif.cmx Op.cmx Mach.cmx Locations.cmx Lineartyping.cmx \
- Linear.cmx Integers.cmx Datatypes.cmx Coqlib.cmx Conventions.cmx \
- CList.cmx BinPos.cmx BinInt.cmx AST.cmx Stacking.cmi
+Stacking.cmo: Specif.cmi Op.cmi Mach.cmi Locations.cmi Linear.cmi \
+ Integers.cmi Errors.cmi Datatypes.cmi Coqlib.cmi Conventions.cmi \
+ CString.cmi CList.cmi Bounds.cmi BinPos.cmi BinInt.cmi Ascii.cmi AST.cmi \
+ Stacking.cmi
+Stacking.cmx: Specif.cmx Op.cmx Mach.cmx Locations.cmx Linear.cmx \
+ Integers.cmx Errors.cmx Datatypes.cmx Coqlib.cmx Conventions.cmx \
+ CString.cmx CList.cmx Bounds.cmx BinPos.cmx BinInt.cmx Ascii.cmx AST.cmx \
+ Stacking.cmi
Sumbool.cmo: Specif.cmi Datatypes.cmi Sumbool.cmi
Sumbool.cmx: Specif.cmx Datatypes.cmx Sumbool.cmi
+Switch.cmo: Integers.cmi EqNat.cmi Datatypes.cmi CList.cmi Switch.cmi
+Switch.cmx: Integers.cmx EqNat.cmx Datatypes.cmx CList.cmx Switch.cmi
Tunneling.cmo: Maps.cmi LTL.cmi Datatypes.cmi AST.cmi Tunneling.cmi
Tunneling.cmx: Maps.cmx LTL.cmx Datatypes.cmx AST.cmx Tunneling.cmi
Values.cmo: Specif.cmi Integers.cmi Floats.cmi Datatypes.cmi Coqlib.cmi \
diff --git a/extraction/Makefile b/extraction/Makefile
index 69b5f57..cb7f4c5 100644
--- a/extraction/Makefile
+++ b/extraction/Makefile
@@ -1,32 +1,36 @@
FILES=\
- Datatypes.ml Logic.ml Wf.ml Peano.ml Specif.ml Compare_dec.ml \
+ Datatypes.ml Logic.ml Wf.ml Peano.ml Specif.ml Compare_dec.ml EqNat.ml \
Bool.ml CList.ml Sumbool.ml Setoid.ml BinPos.ml BinNat.ml BinInt.ml \
ZArith_dec.ml Zeven.ml Zmax.ml Zmisc.ml Zbool.ml Zpower.ml Zdiv.ml \
+ Ascii.ml CString.ml \
OrderedType.ml FSetInterface.ml FSetFacts.ml FSetList.ml \
CInt.ml FSetAVL.ml \
- Coqlib.ml Maps.ml Ordered.ml AST.ml Iteration.ml Integers.ml \
+ Coqlib.ml Maps.ml Ordered.ml Errors.ml AST.ml Iteration.ml Integers.ml \
../caml/Camlcoq.ml ../caml/Floataux.ml Floats.ml Parmov.ml Values.ml \
Mem.ml Globalenvs.ml \
- Csyntax.ml Ctyping.ml Csharpminor.ml Cshmgen.ml \
- Op.ml Cminor.ml Cmconstr.ml \
+ Csyntax.ml Ctyping.ml Cminor.ml Csharpminor.ml Cshmgen.ml \
Cminorgen.ml \
+ Op.ml CminorSel.ml \
+ Selection.ml \
Registers.ml RTL.ml \
- ../caml/RTLgenaux.ml RTLgen.ml \
+ Switch.ml ../caml/RTLgenaux.ml RTLgen.ml \
Locations.ml Conventions.ml \
../caml/RTLtypingaux.ml RTLtyping.ml \
Lattice.ml Kildall.ml \
Constprop.ml CSE.ml \
- LTL.ml \
+ LTL.ml LTLin.ml \
InterfGraph.ml ../caml/Coloringaux.ml Coloring.ml \
- Parallelmove.ml Allocation.ml \
- Tunneling.ml Linear.ml Lineartyping.ml Linearize.ml \
- Mach.ml Stacking.ml \
+ Allocation.ml \
+ Tunneling.ml Linear.ml Linearize.ml \
+ Parallelmove.ml Reload.ml \
+ Mach.ml Bounds.ml Stacking.ml \
PPC.ml PPCgen.ml \
Main.ml \
../caml/Cil2Csyntax.ml \
../caml/CMparser.ml ../caml/CMlexer.ml ../caml/CMtypecheck.ml \
../caml/PrintCsyntax.ml ../caml/PrintPPC.ml \
../caml/Main2.ml
+# ../caml/Configuration.ml ../caml/Driver.ml
EXTRACTEDFILES:=$(filter-out ../caml/%, $(FILES))
GENFILES:=$(EXTRACTEDFILES) $(EXTRACTEDFILES:.ml=.mli)
@@ -58,13 +62,15 @@ extraction:
@echo "Fixing file names..."
@mv list.ml CList.ml
@mv list.mli CList.mli
+ @mv string.ml CString.ml
+ @mv string.mli CString.mli
@mv int.ml CInt.ml
@mv int.mli CInt.mli
@for i in $(GENFILES); do \
j=`./uncapitalize $$i`; \
test -f $$i || (test -f $$j && mv $$j $$i); \
done
- @echo "Conversion List -> CList and Int -> CInt..."
+ @echo "Conversion List -> CList, String -> CString, Int -> CInt..."
@./convert $(GENFILES)
@echo "Patching files..."
@for i in *.patch; do patch < $$i; done
diff --git a/extraction/convert b/extraction/convert
index a29178a..b3d2533 100755
--- a/extraction/convert
+++ b/extraction/convert
@@ -1,6 +1,7 @@
#!/usr/bin/perl -pi
s/\bList\b/CList/g;
+s/\bString\b/CString/g;
s/\bInt\.Z_as_Int\b/CInt.Z_as_Int/g;
s/\bInt\.Int\b/CInt.Int/g;
s/\bInt\.MoreInt\b/CInt.MoreInt/g;
diff --git a/extraction/extraction.v b/extraction/extraction.v
index 47c6f36..cc33c98 100644
--- a/extraction/extraction.v
+++ b/extraction/extraction.v
@@ -38,6 +38,7 @@ Extract Constant Iteration.GenIter.iterate =>
(* RTLgen *)
+Extract Constant RTLgen.compile_switch => "RTLgenaux.compile_switch".
Extract Constant RTLgen.more_likely => "RTLgenaux.more_likely".
(* RTLtyping *)
diff --git a/lib/Coqlib.v b/lib/Coqlib.v
index 184fe28..7bee366 100644
--- a/lib/Coqlib.v
+++ b/lib/Coqlib.v
@@ -23,6 +23,8 @@ Axiom proof_irrelevance:
(** * Useful tactics *)
+Ltac inv H := inversion H; clear H; subst.
+
Ltac predSpec pred predspec x y :=
generalize (predspec x y); case (pred x y); intro.
@@ -753,6 +755,44 @@ Proof.
generalize list_norepet_app; firstorder.
Qed.
+(** [is_tail l1 l2] holds iff [l2] is of the form [l ++ l1] for some [l]. *)
+
+Inductive is_tail (A: Set): list A -> list A -> Prop :=
+ | is_tail_refl:
+ forall c, is_tail c c
+ | is_tail_cons:
+ forall i c1 c2, is_tail c1 c2 -> is_tail c1 (i :: c2).
+
+Lemma is_tail_in:
+ forall (A: Set) (i: A) c1 c2, is_tail (i :: c1) c2 -> In i c2.
+Proof.
+ induction c2; simpl; intros.
+ inversion H.
+ inversion H. tauto. right; auto.
+Qed.
+
+Lemma is_tail_cons_left:
+ forall (A: Set) (i: A) c1 c2, is_tail (i :: c1) c2 -> is_tail c1 c2.
+Proof.
+ induction c2; intros; inversion H.
+ constructor. constructor. constructor. auto.
+Qed.
+
+Hint Resolve is_tail_refl is_tail_cons is_tail_in is_tail_cons_left: coqlib.
+
+Lemma is_tail_incl:
+ forall (A: Set) (l1 l2: list A), is_tail l1 l2 -> incl l1 l2.
+Proof.
+ induction 1; eauto with coqlib.
+Qed.
+
+Lemma is_tail_trans:
+ forall (A: Set) (l1 l2: list A),
+ is_tail l1 l2 -> forall (l3: list A), is_tail l2 l3 -> is_tail l1 l3.
+Proof.
+ induction 1; intros. auto. apply IHis_tail. eapply is_tail_cons_left; eauto.
+Qed.
+
(** [list_forall2 P [x1 ... xN] [y1 ... yM] holds iff [N = M] and
[P xi yi] holds for all [i]. *)
diff --git a/lib/Iteration.v b/lib/Iteration.v
index 3c4b599..85c5ded 100644
--- a/lib/Iteration.v
+++ b/lib/Iteration.v
@@ -1,6 +1,5 @@
(* Bounded and unbounded iterators *)
-Require Recdef.
Require Import Coqlib.
Require Import Classical.
Require Import Max.
@@ -72,15 +71,51 @@ Fixpoint iterate (a: A) : B :=
Definition num_iterations := 1000000000000%positive.
-Function iter (niter: positive) (s: A) {wf Plt niter} : option B :=
- if peq niter xH then None else
- match step s with
- | inl res => Some res
- | inr s' => iter (Ppred niter) s'
- end.
+(** The simple definition of bounded iteration is:
+<<
+Fixpoint iterate (niter: nat) (a: A) {struct niter} : option B :=
+ match niter with
+ | O => None
+ | S niter' =>
+ match step a with
+ | inl b => b
+ | inr a' => iterate niter' a'
+ end
+ end.
+>>
+ This function is structural recursive over the parameter [niter]
+ (number of iterations), represented here as a Peano integer (type [nat]).
+ However, we want to use very large values of [niter]. As Peano integers,
+ these values would be much too large to fit in memory. Therefore,
+ we must express iteration counts as a binary integer (type [positive]).
+ However, Peano induction over type [positive] is not structural recursion,
+ so we cannot define [iterate] as a Coq fixpoint and must use
+ Noetherian recursion instead. *)
+
+Definition iter_step (x: positive)
+ (next: forall y, Plt y x -> A -> option B)
+ (s: A) : option B :=
+ match peq x xH with
+ | left EQ => None
+ | right NOTEQ =>
+ match step s with
+ | inl res => Some res
+ | inr s' => next (Ppred x) (Ppred_Plt x NOTEQ) s'
+ end
+ end.
+
+Definition iter: positive -> A -> option B :=
+ Fix Plt_wf (fun _ => A -> option B) iter_step.
+
+(** We then prove the expected unrolling equations for [iter]. *)
+
+Remark unroll_iter:
+ forall x, iter x = iter_step x (fun y _ => iter y).
Proof.
- intros. apply Ppred_Plt. auto.
- apply Plt_wf.
+ unfold iter; apply (Fix_eq Plt_wf (fun _ => A -> option B) iter_step).
+ intros. unfold iter_step. apply extensionality. intro s.
+ case (peq x xH); intro. auto.
+ rewrite H. auto.
Qed.
(** The [iterate] function is defined as [iter] up to
@@ -100,10 +135,13 @@ Hypothesis step_prop:
Lemma iter_prop:
forall n a b, P a -> iter n a = Some b -> Q b.
Proof.
- intros n a. functional induction (iter n a); intros.
- discriminate.
- inversion H0; subst b. generalize (step_prop s H). rewrite e0. auto.
- apply IHo. generalize (step_prop s H). rewrite e0. auto. auto.
+ apply (well_founded_ind Plt_wf
+ (fun p => forall a b, P a -> iter p a = Some b -> Q b)).
+ intros until b. intro. rewrite unroll_iter.
+ unfold iter_step. case (peq x 1); intro. congruence.
+ generalize (step_prop a H0).
+ case (step a); intros. congruence.
+ apply H with (Ppred x) a0. apply Ppred_Plt; auto. auto. auto.
Qed.
Lemma iterate_prop:
diff --git a/lib/Parmov.v b/lib/Parmov.v
index cd24dd9..c244b8b 100644
--- a/lib/Parmov.v
+++ b/lib/Parmov.v
@@ -34,30 +34,57 @@
#</A>#
*)
+Require Import Relations.
Require Import Coqlib.
Require Recdef.
Section PARMOV.
+(** * Registers, moves, and their semantics *)
+
+(** The development is parameterized by the type of registers,
+ equipped with a decidable equality. *)
+
Variable reg: Set.
+Variable reg_eq : forall (r1 r2: reg), {r1=r2} + {r1<>r2}.
+
+(** The [temp] function maps every register [r] to the register that
+ should be used to save the value of [r] temporarily while performing
+ a cyclic assignment involving [r]. In the simplest case, there is
+ only one such temporary register [rtemp] and [temp] is the constant
+ function [fun r => rtemp]. In more realistic cases, different temporary
+ registers can be used to hold different values. In the case of Compcert,
+ we have two temporary registers, one for integer values and the other
+ for floating-point values, and [temp] returns the appropriate temporary
+ depending on the type of its argument. *)
+
Variable temp: reg -> reg.
+(** A set of moves is a list of pairs of registers, of the form
+ (source, destination). *)
+
Definition moves := (list (reg * reg))%type. (* src -> dst *)
Definition srcs (m: moves) := List.map (@fst reg reg) m.
Definition dests (m: moves) := List.map (@snd reg reg) m.
-(* Semantics of moves *)
+(** ** Semantics of moves *)
+
+(** The dynamic semantics of moves is given in terms of environments.
+ An environment is a mapping of registers to their current values. *)
Variable val: Set.
Definition env := reg -> val.
-Variable reg_eq : forall (r1 r2: reg), {r1=r2} + {r1<>r2}.
Lemma env_ext:
forall (e1 e2: env),
(forall r, e1 r = e2 r) -> e1 = e2.
Proof (extensionality reg val).
+(** The main operation over environments is update: it assigns
+ a value [v] to a register [r] and preserves the values of other
+ registers. *)
+
Definition update (r: reg) (v: val) (e: env) : env :=
fun r' => if reg_eq r' r then v else e r'.
@@ -97,18 +124,32 @@ Proof.
destruct (reg_eq r0 r); auto.
Qed.
+(** A list of moves [(src1, dst1), ..., (srcN, dstN)] can be given
+ three different semantics, as environment transformers.
+ The first semantics corresponds to a parallel assignment:
+ [dst1, ..., dstN] are set to the initial values of [src1, ..., srcN]. *)
+
Fixpoint exec_par (m: moves) (e: env) {struct m}: env :=
match m with
| nil => e
| (s, d) :: m' => update d (e s) (exec_par m' e)
end.
+(** The second semantics corresponds to a sequence of individual
+ assignments: first, [dst1] is set to the initial value of [src1];
+ then, [dst2] is set to the current value of [src2] after the first
+ assignment; etc. *)
+
Fixpoint exec_seq (m: moves) (e: env) {struct m}: env :=
match m with
| nil => e
| (s, d) :: m' => exec_seq m' (update d (e s) e)
end.
+(** The third semantics is also sequential, but executes the moves
+ in reverse order, starting with [srcN, dstN] and finishing with
+ [src1, dst1]. *)
+
Fixpoint exec_seq_rev (m: moves) (e: env) {struct m}: env :=
match m with
| nil => e
@@ -117,50 +158,57 @@ Fixpoint exec_seq_rev (m: moves) (e: env) {struct m}: env :=
update d (e' s) e'
end.
-(* Specification of the parallel move *)
+(** * Specification of the non-deterministic algorithm *)
+
+(** Rideau and Serpette's parallel move compilation algorithm is first
+ specified as a non-deterministic set of rewriting rules operating
+ over triples [(mu, sigma, tau)] of moves. We define these rules
+ as an inductive predicate [transition] relating triples of moves,
+ and its reflexive transitive closure [transitions]. *)
+
+Inductive state: Set :=
+ State (mu: moves) (sigma: moves) (tau: moves) : state.
Definition no_read (mu: moves) (d: reg) : Prop :=
~In d (srcs mu).
-Inductive transition: moves -> moves -> moves
- -> moves -> moves -> moves -> Prop :=
+Inductive transition: state -> state -> Prop :=
| tr_nop: forall mu1 r mu2 sigma tau,
- transition (mu1 ++ (r, r) :: mu2) sigma tau
- (mu1 ++ mu2) sigma tau
+ transition (State (mu1 ++ (r, r) :: mu2) sigma tau)
+ (State (mu1 ++ mu2) sigma tau)
| tr_start: forall mu1 s d mu2 tau,
- transition (mu1 ++ (s, d) :: mu2) nil tau
- (mu1 ++ mu2) ((s, d) :: nil) tau
+ transition (State (mu1 ++ (s, d) :: mu2) nil tau)
+ (State (mu1 ++ mu2) ((s, d) :: nil) tau)
| tr_push: forall mu1 d r mu2 s sigma tau,
- transition (mu1 ++ (d, r) :: mu2) ((s, d) :: sigma) tau
- (mu1 ++ mu2) ((d, r) :: (s, d) :: sigma) tau
+ transition (State (mu1 ++ (d, r) :: mu2) ((s, d) :: sigma) tau)
+ (State (mu1 ++ mu2) ((d, r) :: (s, d) :: sigma) tau)
| tr_loop: forall mu sigma s d tau,
- transition mu (sigma ++ (s, d) :: nil) tau
- mu (sigma ++ (temp s, d) :: nil) ((s, temp s) :: tau)
+ transition (State mu (sigma ++ (s, d) :: nil) tau)
+ (State mu (sigma ++ (temp s, d) :: nil) ((s, temp s) :: tau))
| tr_pop: forall mu s0 d0 s1 d1 sigma tau,
no_read mu d1 -> d1 <> s0 ->
- transition mu ((s1, d1) :: sigma ++ (s0, d0) :: nil) tau
- mu (sigma ++ (s0, d0) :: nil) ((s1, d1) :: tau)
+ transition (State mu ((s1, d1) :: sigma ++ (s0, d0) :: nil) tau)
+ (State mu (sigma ++ (s0, d0) :: nil) ((s1, d1) :: tau))
| tr_last: forall mu s d tau,
no_read mu d ->
- transition mu ((s, d) :: nil) tau
- mu nil ((s, d) :: tau).
+ transition (State mu ((s, d) :: nil) tau)
+ (State mu nil ((s, d) :: tau)).
-Inductive transitions: moves -> moves -> moves
- -> moves -> moves -> moves -> Prop :=
- | tr_refl:
- forall mu sigma tau,
- transitions mu sigma tau mu sigma tau
- | tr_one:
- forall mu1 sigma1 tau1 mu2 sigma2 tau2,
- transition mu1 sigma1 tau1 mu2 sigma2 tau2 ->
- transitions mu1 sigma1 tau1 mu2 sigma2 tau2
- | tr_trans:
- forall mu1 sigma1 tau1 mu2 sigma2 tau2 mu3 sigma3 tau3,
- transitions mu1 sigma1 tau1 mu2 sigma2 tau2 ->
- transitions mu2 sigma2 tau2 mu3 sigma3 tau3 ->
- transitions mu1 sigma1 tau1 mu3 sigma3 tau3.
-
-(* Well-formedness properties *)
+Definition transitions: state -> state -> Prop :=
+ clos_refl_trans state transition.
+
+(** ** Well-formedness properties of states *)
+
+(** A state [mu, sigma, tau] is well-formed if the following properties hold:
+
+- [mu] concatenated with [sigma] is a ``mill'', that is, no destination
+ appears twice (predicate [is_mill] below).
+- No temporary register appears in [mu] (predicate [move_no_temp]).
+- No temporary register appears in [sigma] except perhaps as the source
+ of the last move in [sigma] (predicate [temp_last]).
+- [sigma] is a ``path'', that is, the source of a move is the destination
+ of the following move.
+*)
Definition is_mill (m: moves) : Prop :=
list_norepet (dests m).
@@ -191,13 +239,16 @@ Inductive is_path: moves -> Prop :=
is_path m ->
is_path ((s, d) :: m).
-Definition state_wf (mu sigma tau: moves) : Prop :=
- is_mill (mu ++ sigma)
- /\ move_no_temp mu
- /\ temp_last sigma
- /\ is_path sigma.
+Inductive state_wf: state -> Prop :=
+ | state_wf_intro:
+ forall mu sigma tau,
+ is_mill (mu ++ sigma) ->
+ move_no_temp mu ->
+ temp_last sigma ->
+ is_path sigma ->
+ state_wf (State mu sigma tau).
-(* Some properties of srcs and dests *)
+(** Some trivial properties of srcs and dests. *)
Lemma dests_append:
forall m1 m2, dests (m1 ++ m2) = dests m1 ++ dests m2.
@@ -236,7 +287,7 @@ Proof.
elim (IHs d); intros. split; congruence. congruence.
Qed.
-(* Some properties of is_mill and dests_disjoint *)
+(** Some properties of [is_mill] and [dests_disjoint]. *)
Definition dests_disjoint (m1 m2: moves) : Prop :=
list_disjoint (dests m1) (dests m2).
@@ -313,7 +364,7 @@ Proof.
apply list_norepet_app.
Qed.
-(* Some properties of move_no_temp *)
+(** Some properties of [move_no_temp]. *)
Lemma move_no_temp_append:
forall m1 m2,
@@ -329,7 +380,7 @@ Proof.
intros; red; intros. apply H. rewrite <- List.In_rev. auto.
Qed.
-(* Some properties of temp_last *)
+(** Some properties of [temp_last]. *)
Lemma temp_last_change_last_source:
forall s d s' sigma,
@@ -369,7 +420,7 @@ Proof.
apply in_or_app. auto.
Qed.
-(* Some properties of is_path *)
+(** Some properties of [is_path]. *)
Lemma is_path_pop:
forall s d m,
@@ -420,7 +471,8 @@ Proof.
intro. elim H1. elim (H2 _ H3); intro. congruence. auto.
Qed.
-(* Populating a rewrite database. *)
+(** To benefit from some proof automation, we populate a rewrite database
+ with some of the properties above. *)
Lemma notin_dests_cons:
forall x s d m,
@@ -441,65 +493,76 @@ Hint Rewrite is_mill_cons is_mill_append
dests_disjoint_append_left dests_disjoint_append_right
notin_dests_cons notin_dests_append: pmov.
-(* Preservation of well-formedness *)
+(** ** Transitions preserve well-formedness *)
Lemma transition_preserves_wf:
- forall mu sigma tau mu' sigma' tau',
- transition mu sigma tau mu' sigma' tau' ->
- state_wf mu sigma tau -> state_wf mu' sigma' tau'.
+ forall st st',
+ transition st st' -> state_wf st -> state_wf st'.
Proof.
- induction 1; unfold state_wf; intros [A [B [C D]]];
- autorewrite with pmov in A; autorewrite with pmov.
+ induction 1; intro WF; inversion WF as [mu0 sigma0 tau0 A B C D];
+ subst;
+ autorewrite with pmov in A; constructor; autorewrite with pmov.
(* Nop *)
- split. tauto.
- split. red; intros. apply B. apply list_in_insert; auto.
- split; auto.
+ tauto.
+ red; intros. apply B. apply list_in_insert; auto.
+ auto. auto.
(* Start *)
- split. tauto.
- split. red; intros. apply B. apply list_in_insert; auto.
- split. red. simpl. split. elim (B s d). auto.
+ tauto.
+ red; intros. apply B. apply list_in_insert; auto.
+ red. simpl. split. elim (B s d). auto.
apply in_or_app. right. apply in_eq.
red; simpl; tauto.
constructor. exact I. constructor.
(* Push *)
- split. intuition.
- split. red; intros. apply B. apply list_in_insert; auto.
- split. elim (B d r). apply temp_last_push; auto.
+ intuition.
+ red; intros. apply B. apply list_in_insert; auto.
+ elim (B d r). apply temp_last_push; auto.
apply in_or_app; right; apply in_eq.
constructor. simpl. auto. auto.
(* Loop *)
- split. tauto.
- split. auto.
- split. eapply temp_last_change_last_source; eauto.
+ tauto.
+ auto.
+ eapply temp_last_change_last_source; eauto.
eapply is_path_change_last_source; eauto.
(* Pop *)
- split. intuition.
- split. auto.
- split. eapply temp_last_pop; eauto.
+ intuition.
+ auto.
+ eapply temp_last_pop; eauto.
eapply is_path_pop; eauto.
(* Last *)
- split. intuition.
- split. auto.
- split. unfold temp_last. simpl. auto.
+ intuition.
+ auto.
+ unfold temp_last. simpl. auto.
constructor.
Qed.
Lemma transitions_preserve_wf:
- forall mu sigma tau mu' sigma' tau',
- transitions mu sigma tau mu' sigma' tau' ->
- state_wf mu sigma tau -> state_wf mu' sigma' tau'.
+ forall st st', transitions st st' -> state_wf st -> state_wf st'.
Proof.
induction 1; intros; eauto.
eapply transition_preserves_wf; eauto.
Qed.
-(* Properties of exec_ *)
+(** ** Transitions preserve semantics *)
+
+(** We define the semantics of states as follows.
+ For a triple [mu, sigma, tau], we perform the moves [tau] in
+ reverse sequential order, then the moves [mu ++ sigma] in parallel. *)
+
+Definition statemove (st: state) (e: env) :=
+ match st with
+ | State mu sigma tau => exec_par (mu ++ sigma) (exec_seq_rev tau e)
+ end.
+
+(** In preparation to showing that transitions preserve semantics,
+ we prove various properties of the parallel and sequential interpretations
+ of moves. *)
Lemma exec_par_outside:
forall m e r, ~In r (dests m) -> exec_par m e r = e r.
@@ -609,12 +672,10 @@ Proof.
intros. rewrite update_o. apply B. tauto. intuition.
Qed.
-(* Semantics of triples (mu, sigma, tau) *)
-
-Definition statemove (mu sigma tau: moves) (e: env) :=
- exec_par (mu ++ sigma) (exec_seq_rev tau e).
-
-(* Equivalence over non-temp regs *)
+(** [env_equiv] is an equivalence relation between environments
+ capturing the fact that two environments assign the same values to
+ non-temporary registers, but can disagree on the values of temporary
+ registers. *)
Definition env_equiv (e1 e2: env) : Prop :=
forall r, is_not_temp r -> e1 r = e2 r.
@@ -657,15 +718,15 @@ Proof.
apply IHm; auto.
Qed.
-(* Preservation of semantics by transformations. *)
+(** The proof that transitions preserve semantics (up to the values of
+ temporary registers) follows. *)
Lemma transition_preserves_semantics:
- forall mu1 sigma1 tau1 mu2 sigma2 tau2 e,
- transition mu1 sigma1 tau1 mu2 sigma2 tau2 ->
- state_wf mu1 sigma1 tau1 ->
- env_equiv (statemove mu2 sigma2 tau2 e) (statemove mu1 sigma1 tau1 e).
+ forall st st' e,
+ transition st st' -> state_wf st ->
+ env_equiv (statemove st' e) (statemove st e).
Proof.
- induction 1; intros [A [B [C D]]].
+ induction 1; intro WF; inversion WF as [mu0 sigma0 tau0 A B C D]; subst; simpl.
(* nop *)
apply env_equiv_refl'. unfold statemove.
@@ -728,134 +789,133 @@ Proof.
Qed.
Lemma transitions_preserve_semantics:
- forall mu1 sigma1 tau1 mu2 sigma2 tau2 e,
- transitions mu1 sigma1 tau1 mu2 sigma2 tau2 ->
- state_wf mu1 sigma1 tau1 ->
- env_equiv (statemove mu2 sigma2 tau2 e) (statemove mu1 sigma1 tau1 e).
+ forall st st' e,
+ transitions st st' -> state_wf st ->
+ env_equiv (statemove st' e) (statemove st e).
Proof.
induction 1; intros.
- apply env_equiv_refl.
eapply transition_preserves_semantics; eauto.
- apply env_equiv_trans with (statemove mu2 sigma2 tau2 e).
- apply IHtransitions2. eapply transitions_preserve_wf; eauto.
- apply IHtransitions1. auto.
+ apply env_equiv_refl.
+ apply env_equiv_trans with (statemove y e); auto.
+ apply IHclos_refl_trans2. eapply transitions_preserve_wf; eauto.
Qed.
Lemma state_wf_start:
forall mu,
move_no_temp mu ->
is_mill mu ->
- state_wf mu nil nil.
+ state_wf (State mu nil nil).
Proof.
- split. rewrite <- app_nil_end. auto.
- split. auto.
- split. red. simpl. auto.
+ intros. constructor. rewrite <- app_nil_end. auto.
+ auto.
+ red. simpl. auto.
constructor.
Qed.
+(** The main correctness result in this section is the following:
+ if we can transition repeatedly from an initial state [mu, nil, nil]
+ to a final state [nil, nil, tau], then the sequential execution
+ of the moves [rev tau] is semantically equivalent to the parallel
+ execution of the moves [mu]. *)
+
Theorem transitions_correctness:
forall mu tau,
move_no_temp mu ->
is_mill mu ->
- transitions mu nil nil nil nil tau ->
+ transitions (State mu nil nil) (State nil nil tau) ->
forall e, env_equiv (exec_seq (List.rev tau) e) (exec_par mu e).
Proof.
intros.
- generalize (transitions_preserve_semantics _ _ _ _ _ _ e H1
+ generalize (transitions_preserve_semantics _ _ e H1
(state_wf_start _ H H0)).
unfold statemove. simpl. rewrite <- app_nil_end.
rewrite exec_seq_exec_seq_rev. auto.
Qed.
-(* Determinisation of the transition relation *)
+(** * Determinisation of the transition relation *)
+
+(** We now define a deterministic variant [dtransition] of the
+ transition relation [transition]. [dtransition] is deterministic
+ in the sense that at most one transition applies to a given state. *)
-Inductive dtransition: moves -> moves -> moves
- -> moves -> moves -> moves -> Prop :=
+Inductive dtransition: state -> state -> Prop :=
| dtr_nop: forall r mu tau,
- dtransition ((r, r) :: mu) nil tau
- mu nil tau
+ dtransition (State ((r, r) :: mu) nil tau)
+ (State mu nil tau)
| dtr_start: forall s d mu tau,
s <> d ->
- dtransition ((s, d) :: mu) nil tau
- mu ((s, d) :: nil) tau
+ dtransition (State ((s, d) :: mu) nil tau)
+ (State mu ((s, d) :: nil) tau)
| dtr_push: forall mu1 d r mu2 s sigma tau,
no_read mu1 d ->
- dtransition (mu1 ++ (d, r) :: mu2) ((s, d) :: sigma) tau
- (mu1 ++ mu2) ((d, r) :: (s, d) :: sigma) tau
+ dtransition (State (mu1 ++ (d, r) :: mu2) ((s, d) :: sigma) tau)
+ (State (mu1 ++ mu2) ((d, r) :: (s, d) :: sigma) tau)
| dtr_loop_pop: forall mu s r0 d sigma tau,
no_read mu r0 ->
- dtransition mu ((s, r0) :: sigma ++ (r0, d) :: nil) tau
- mu (sigma ++ (temp r0, d) :: nil) ((s, r0) :: (r0, temp r0) :: tau)
+ dtransition (State mu ((s, r0) :: sigma ++ (r0, d) :: nil) tau)
+ (State mu (sigma ++ (temp r0, d) :: nil) ((s, r0) :: (r0, temp r0) :: tau))
| dtr_pop: forall mu s0 d0 s1 d1 sigma tau,
no_read mu d1 -> d1 <> s0 ->
- dtransition mu ((s1, d1) :: sigma ++ (s0, d0) :: nil) tau
- mu (sigma ++ (s0, d0) :: nil) ((s1, d1) :: tau)
+ dtransition (State mu ((s1, d1) :: sigma ++ (s0, d0) :: nil) tau)
+ (State mu (sigma ++ (s0, d0) :: nil) ((s1, d1) :: tau))
| dtr_last: forall mu s d tau,
no_read mu d ->
- dtransition mu ((s, d) :: nil) tau
- mu nil ((s, d) :: tau).
+ dtransition (State mu ((s, d) :: nil) tau)
+ (State mu nil ((s, d) :: tau)).
-Inductive dtransitions: moves -> moves -> moves
- -> moves -> moves -> moves -> Prop :=
- | dtr_refl:
- forall mu sigma tau,
- dtransitions mu sigma tau mu sigma tau
- | dtr_one:
- forall mu1 sigma1 tau1 mu2 sigma2 tau2,
- dtransition mu1 sigma1 tau1 mu2 sigma2 tau2 ->
- dtransitions mu1 sigma1 tau1 mu2 sigma2 tau2
- | dtr_trans:
- forall mu1 sigma1 tau1 mu2 sigma2 tau2 mu3 sigma3 tau3,
- dtransitions mu1 sigma1 tau1 mu2 sigma2 tau2 ->
- dtransitions mu2 sigma2 tau2 mu3 sigma3 tau3 ->
- dtransitions mu1 sigma1 tau1 mu3 sigma3 tau3.
+Definition dtransitions: state -> state -> Prop :=
+ clos_refl_trans state dtransition.
+
+(** Every deterministic transition corresponds to a sequence of
+ non-deterministic transitions. *)
Lemma transition_determ:
- forall mu1 sigma1 tau1 mu2 sigma2 tau2,
- dtransition mu1 sigma1 tau1 mu2 sigma2 tau2 ->
- state_wf mu1 sigma1 tau1 ->
- transitions mu1 sigma1 tau1 mu2 sigma2 tau2.
-Proof.
- induction 1; intro.
- apply tr_one. exact (tr_nop nil r mu nil tau).
- apply tr_one. exact (tr_start nil s d mu tau).
- apply tr_one. apply tr_push.
- eapply tr_trans.
- apply tr_one.
+ forall st st',
+ dtransition st st' ->
+ state_wf st ->
+ transitions st st'.
+Proof.
+ induction 1; intro; unfold transitions.
+ apply rt_step. exact (tr_nop nil r mu nil tau).
+ apply rt_step. exact (tr_start nil s d mu tau).
+ apply rt_step. apply tr_push.
+ eapply rt_trans.
+ apply rt_step.
change ((s, r0) :: sigma ++ (r0, d) :: nil)
with (((s, r0) :: sigma) ++ (r0, d) :: nil).
apply tr_loop.
- apply tr_one. simpl. apply tr_pop. auto.
- destruct H0 as [A [B [C D]]].
- generalize C.
+ apply rt_step. simpl. apply tr_pop. auto.
+ inv H0. generalize H6.
change ((s, r0) :: sigma ++ (r0, d) :: nil)
with (((s, r0) :: sigma) ++ (r0, d) :: nil).
unfold temp_last; rewrite List.rev_unit. intros [E F].
elim (F s r0). unfold is_not_temp. auto.
rewrite <- List.In_rev. apply in_eq.
- apply tr_one. apply tr_pop. auto. auto.
- apply tr_one. apply tr_last. auto.
+ apply rt_step. apply tr_pop. auto. auto.
+ apply rt_step. apply tr_last. auto.
Qed.
Lemma transitions_determ:
- forall mu1 sigma1 tau1 mu2 sigma2 tau2,
- dtransitions mu1 sigma1 tau1 mu2 sigma2 tau2 ->
- state_wf mu1 sigma1 tau1 ->
- transitions mu1 sigma1 tau1 mu2 sigma2 tau2.
+ forall st st',
+ dtransitions st st' ->
+ state_wf st ->
+ transitions st st'.
Proof.
- induction 1; intros.
- apply tr_refl.
+ unfold transitions; induction 1; intros.
eapply transition_determ; eauto.
- eapply tr_trans.
- apply IHdtransitions1. auto.
- apply IHdtransitions2. eapply transitions_preserve_wf; eauto.
+ apply rt_refl.
+ apply rt_trans with y. auto.
+ apply IHclos_refl_trans2.
+ apply transitions_preserve_wf with x; auto. red; auto.
Qed.
+(** The semantic correctness of deterministic transitions follows. *)
+
Theorem dtransitions_correctness:
forall mu tau,
move_no_temp mu ->
is_mill mu ->
- dtransitions mu nil nil nil nil tau ->
+ dtransitions (State mu nil nil) (State nil nil tau) ->
forall e, env_equiv (exec_seq (List.rev tau) e) (exec_par mu e).
Proof.
intros.
@@ -863,7 +923,11 @@ Proof.
apply transitions_determ. auto. apply state_wf_start; auto.
Qed.
-(* Transition function *)
+(** * The compilation function *)
+
+(** We now define a function that takes a well-formed parallel move [mu]
+ and returns a sequence of elementary moves [tau] that is semantically
+ equivalent. We start by defining a number of auxiliary functions. *)
Function split_move (m: moves) (r: reg) {struct m} : option (moves * reg * moves) :=
match m with
@@ -893,8 +957,6 @@ Function replace_last_source (r: reg) (m: moves) {struct m} : moves :=
| s_d :: tl => s_d :: replace_last_source r tl
end.
-Inductive state : Set := State: moves -> moves -> moves -> state.
-
Definition final_state (st: state) : bool :=
match st with
| State nil nil _ => true
@@ -923,7 +985,7 @@ Function parmove_step (st: state) : state :=
end
end.
-(* Correctness properties of these functions *)
+(** Here are the main correctness properties of these functions. *)
Lemma split_move_charact:
forall m r,
@@ -966,54 +1028,50 @@ Proof.
Qed.
Lemma parmove_step_compatible:
- forall mu sigma tau mu' sigma' tau',
- final_state (State mu sigma tau) = false ->
- parmove_step (State mu sigma tau) = State mu' sigma' tau' ->
- dtransition mu sigma tau mu' sigma' tau'.
+ forall st,
+ final_state st = false ->
+ dtransition st (parmove_step st).
Proof.
- intros until tau'. intro NOTFINAL.
- unfold parmove_step.
+ intros st NOTFINAL. destruct st as [mu sigma tau]. unfold parmove_step.
case_eq mu; [intros MEQ | intros [ms md] mtl MEQ].
case_eq sigma; [intros SEQ | intros [ss sd] stl SEQ].
- subst mu sigma. discriminate.
+ subst mu sigma. simpl in NOTFINAL. discriminate.
simpl.
case_eq stl; [intros STLEQ | intros xx1 xx2 STLEQ].
- intro R; inversion R; clear R; subst.
apply dtr_last. red; simpl; auto.
elim (@exists_last _ stl). 2:congruence. intros sigma1 [[ss1 sd1] SEQ2].
rewrite <- STLEQ. clear STLEQ xx1 xx2.
generalize (is_last_source_charact sd ss1 sd1 sigma1).
rewrite SEQ2. destruct (is_last_source sd (sigma1 ++ (ss1, sd1) :: nil)).
- intro. subst ss1. intro R; inversion R; clear R; subst.
+ intro. subst ss1.
rewrite replace_last_source_charact. apply dtr_loop_pop.
red; simpl; auto.
- intro. intro R; inversion R; clear R; subst.
- apply dtr_pop. red; simpl; auto. auto.
+ intro. apply dtr_pop. red; simpl; auto. auto.
case_eq sigma; [intros SEQ | intros [ss sd] stl SEQ].
- destruct (reg_eq ms md); intro R; inversion R; clear R; subst.
- apply dtr_nop.
+ destruct (reg_eq ms md).
+ subst. apply dtr_nop.
apply dtr_start. auto.
generalize (split_move_charact ((ms, md) :: mtl) sd).
case (split_move ((ms, md) :: mtl) sd); [intros [[before r] after] | idtac].
- intros [MEQ2 NOREAD]. intro R; inversion R; clear R; subst.
+ intros [MEQ2 NOREAD].
rewrite MEQ2. apply dtr_push. auto.
intro NOREAD.
case_eq stl; [intros STLEQ | intros xx1 xx2 STLEQ].
- intro R; inversion R; clear R; subst.
apply dtr_last. auto.
elim (@exists_last _ stl). 2:congruence. intros sigma1 [[ss1 sd1] SEQ2].
rewrite <- STLEQ. clear STLEQ xx1 xx2.
generalize (is_last_source_charact sd ss1 sd1 sigma1).
rewrite SEQ2. destruct (is_last_source sd (sigma1 ++ (ss1, sd1) :: nil)).
- intro. subst ss1. intro R; inversion R; clear R; subst.
+ intro. subst ss1.
rewrite replace_last_source_charact. apply dtr_loop_pop. auto.
- intro. intro R; inversion R; clear R; subst.
- apply dtr_pop. auto. auto.
+ intro. apply dtr_pop. auto. auto.
Qed.
-(* Decreasing measure over states *)
+(** The compilation function is obtained by iterating the [parmov_step]
+ function. To show that this iteration always terminates, we introduce
+ the following measure over states. *)
Open Scope nat_scope.
@@ -1023,9 +1081,8 @@ Definition measure (st: state) : nat :=
end.
Lemma measure_decreasing_1:
- forall mu1 sigma1 tau1 mu2 sigma2 tau2,
- dtransition mu1 sigma1 tau1 mu2 sigma2 tau2 ->
- measure (State mu2 sigma2 tau2) < measure (State mu1 sigma1 tau1).
+ forall st st',
+ dtransition st st' -> measure st' < measure st.
Proof.
induction 1; repeat (simpl; rewrite List.app_length); simpl; omega.
Qed.
@@ -1035,13 +1092,10 @@ Lemma measure_decreasing_2:
final_state st = false ->
measure (parmove_step st) < measure st.
Proof.
- intros. destruct st as [mu sigma tau].
- case_eq (parmove_step (State mu sigma tau)). intros mu' sigma' tau' EQ.
- apply measure_decreasing_1.
- apply parmove_step_compatible; auto.
+ intros. apply measure_decreasing_1. apply parmove_step_compatible; auto.
Qed.
-(* Compilation function for parallel moves *)
+(** Compilation function for parallel moves. *)
Function parmove_aux (st: state) {measure measure st} : moves :=
if final_state st
@@ -1052,26 +1106,22 @@ Proof.
Qed.
Lemma parmove_aux_transitions:
- forall mu sigma tau,
- dtransitions mu sigma tau nil nil (parmove_aux (State mu sigma tau)).
+ forall st,
+ dtransitions st (State nil nil (parmove_aux st)).
Proof.
- assert (forall st,
- match st with State mu sigma tau =>
- dtransitions mu sigma tau nil nil (parmove_aux st)
- end).
- intro st. functional induction (parmove_aux st).
- destruct _x; destruct _x0; simpl in e; discriminate || apply dtr_refl.
- case_eq (parmove_step st). intros mu' sigma' tau' PSTEP.
- destruct st as [mu sigma tau].
- eapply dtr_trans. apply dtr_one. apply parmove_step_compatible; eauto.
- rewrite PSTEP in IHm. auto.
-
- intros. apply (H (State mu sigma tau)).
+ unfold dtransitions. intro st. functional induction (parmove_aux st).
+ destruct _x; destruct _x0; simpl in e; discriminate || apply rt_refl.
+ eapply rt_trans. apply rt_step. apply parmove_step_compatible; eauto.
+ auto.
Qed.
Definition parmove (mu: moves) : moves :=
List.rev (parmove_aux (State mu nil nil)).
+(** This is the main correctness theorem: the sequence of elementary
+ moves [parmove mu] is semantically equivalent to the parallel move
+ [mu] if the latter is well-formed. *)
+
Theorem parmove_correctness:
forall mu,
move_no_temp mu -> is_mill mu ->
@@ -1082,6 +1132,10 @@ Proof.
apply parmove_aux_transitions.
Qed.
+(** Here is an alternate formulation of [parmove], where the
+ parallel move problem is given as two separate lists of sources
+ and destinations. *)
+
Definition parmove2 (sl dl: list reg) : moves :=
parmove (List.combine sl dl).
@@ -1111,7 +1165,13 @@ Proof.
intros. transitivity (e1 r); auto.
Qed.
-(* Additional properties on the generated sequence of moves. *)
+(** * Additional syntactic properties *)
+
+(** We now show an additional property of the sequence of moves
+ generated by [parmove mu]: any such move [s -> d] is either
+ already present in [mu], or of the form [temp s -> d] or [s -> temp s]
+ for some [s -> d] in [mu]. This syntactic property is useful
+ to show that [parmove] preserves typing, for instance. *)
Section PROPERTIES.
@@ -1145,36 +1205,23 @@ Qed.
Hint Rewrite wf_moves_cons wf_moves_append: pmov.
-Definition wf_state (mu sigma tau: moves) : Prop :=
- wf_moves mu /\ wf_moves sigma /\ wf_moves tau.
+Inductive wf_state: state -> Prop :=
+ | wf_state_intro: forall mu sigma tau,
+ wf_moves mu -> wf_moves sigma -> wf_moves tau ->
+ wf_state (State mu sigma tau).
Lemma dtransition_preserves_wf_state:
- forall mu1 sigma1 tau1 mu2 sigma2 tau2,
- dtransition mu1 sigma1 tau1 mu2 sigma2 tau2 ->
- wf_state mu1 sigma1 tau1 -> wf_state mu2 sigma2 tau2.
+ forall st st',
+ dtransition st st' -> wf_state st -> wf_state st'.
Proof.
- induction 1; intros [A [B C]]; unfold wf_state;
- autorewrite with pmov in A; autorewrite with pmov in B;
- autorewrite with pmov in C; autorewrite with pmov.
-
- tauto.
-
- tauto.
-
- tauto.
-
- intuition. apply wf_move_temp_left; auto.
+ induction 1; intro WF; inv WF; constructor; autorewrite with pmov in *; intuition.
+ apply wf_move_temp_left; auto.
eapply wf_move_temp_right; eauto.
-
- intuition.
-
- intuition.
Qed.
Lemma dtransitions_preserve_wf_state:
- forall mu1 sigma1 tau1 mu2 sigma2 tau2,
- dtransitions mu1 sigma1 tau1 mu2 sigma2 tau2 ->
- wf_state mu1 sigma1 tau1 -> wf_state mu2 sigma2 tau2.
+ forall st st',
+ dtransitions st st' -> wf_state st -> wf_state st'.
Proof.
induction 1; intros; eauto.
eapply dtransition_preserves_wf_state; eauto.
@@ -1186,14 +1233,14 @@ Lemma parmove_wf_moves:
forall mu, wf_moves mu (parmove mu).
Proof.
intros.
- assert (wf_state mu mu nil nil).
- split. red; intros. apply wf_move_same. auto.
- split. red; simpl; tauto. red; simpl; tauto.
+ assert (wf_state mu (State mu nil nil)).
+ constructor. red; intros. apply wf_move_same. auto.
+ red; simpl; tauto. red; simpl; tauto.
generalize (dtransitions_preserve_wf_state mu
- _ _ _ _ _ _
- (parmove_aux_transitions mu nil nil) H).
- intros [A [B C]].
- unfold parmove. red; intros. apply C.
+ _ _
+ (parmove_aux_transitions (State mu nil nil)) H).
+ intro WFS. inv WFS.
+ unfold parmove. red; intros. apply H5.
rewrite List.In_rev. auto.
Qed.
diff --git a/runtime/Makefile b/runtime/Makefile
new file mode 100644
index 0000000..c45c9fb
--- /dev/null
+++ b/runtime/Makefile
@@ -0,0 +1,13 @@
+CFLAGS=-arch ppc -O1 -g -Wall
+#CFLAGS=-O1 -g -Wall
+OBJS=stdio.o calloc.o
+LIB=libcompcert.a
+
+$(LIB): $(OBJS)
+ rm -f $(LIB)
+ ar rcs $(LIB) $(OBJS)
+
+stdio.o: stdio.h
+
+clean:
+ rm -f *.o $(LIB)
diff --git a/runtime/calloc.c b/runtime/calloc.c
new file mode 100644
index 0000000..2526ceb
--- /dev/null
+++ b/runtime/calloc.c
@@ -0,0 +1,13 @@
+#include <stdio.h>
+#include <stddef.h>
+#include <stdlib.h>
+
+void * compcert_alloc(int sz)
+{
+ void * res = malloc(sz);
+ if (res == NULL) {
+ fprintf(stderr, "Out of memory in compcert_alloc().\n");
+ abort();
+ }
+ return res;
+}
diff --git a/runtime/stdio.c b/runtime/stdio.c
new file mode 100644
index 0000000..c153257
--- /dev/null
+++ b/runtime/stdio.c
@@ -0,0 +1,152 @@
+#include <stdarg.h>
+#include <stdlib.h>
+#define _INSIDE_COMPCERT_COMPATIBILITY_LIBRARY
+#include "stdio.h"
+
+static compcert_FILE * compcert_alloc_file(FILE * f)
+{
+ struct compcert_FILE_ * r;
+ r = malloc(sizeof(struct compcert_FILE_));
+ if (r == NULL) return NULL;
+ r->fstr = (void *) f;
+ return r;
+}
+
+compcert_FILE * compcert_stdin;
+compcert_FILE * compcert_stdout;
+compcert_FILE * compcert_stderr;
+
+static __attribute__((constructor)) void compcert_stdio_init(void)
+{
+ compcert_stdin = compcert_alloc_file(stdin);
+ compcert_stdout = compcert_alloc_file(stdout);
+ compcert_stderr = compcert_alloc_file(stderr);
+}
+
+void compcert_clearerr(compcert_FILE * f)
+{
+ clearerr((FILE *)(f->fstr));
+}
+
+int compcert_fclose(compcert_FILE * f)
+{
+ int errcode = fclose((FILE *)(f->fstr));
+ free(f);
+ return errcode;
+}
+
+int compcert_feof(compcert_FILE * f)
+{
+ return feof((FILE *)(f->fstr));
+}
+
+int compcert_ferror(compcert_FILE * f)
+{
+ return ferror((FILE *)(f->fstr));
+}
+
+int compcert_fflush(compcert_FILE * f)
+{
+ return fflush((FILE *)(f->fstr));
+}
+
+int compcert_fgetc(compcert_FILE * f)
+{
+ return fgetc((FILE *)(f->fstr));
+}
+
+char *compcert_fgets(char * s, int n, compcert_FILE * f)
+{
+ return fgets(s, n, (FILE *)(f->fstr));
+}
+
+compcert_FILE *compcert_fopen(const char * p, const char * m)
+{
+ FILE * f = fopen(p, m);
+ if (f == NULL) return NULL;
+ return compcert_alloc_file(f);
+}
+
+int compcert_fprintf(compcert_FILE * f, const char * s, ...)
+{
+ va_list ap;
+ int retcode;
+ va_start(ap, s);
+ retcode = vfprintf((FILE *)(f->fstr), s, ap);
+ va_end(ap);
+ return retcode;
+}
+
+int compcert_fputc(int c, compcert_FILE * f)
+{
+ return fputc(c, (FILE *)(f->fstr));
+}
+
+int compcert_fputs(const char * s, compcert_FILE * f)
+{
+ return fputs(s, (FILE *)(f->fstr));
+}
+
+size_t compcert_fread(void * s, size_t p, size_t q, compcert_FILE * f)
+{
+ return fread(s, p, q, (FILE *)(f->fstr));
+}
+
+compcert_FILE *compcert_freopen(const char * s, const char * m,
+ compcert_FILE * f)
+{
+ FILE * nf = freopen(s, m, (FILE *)(f->fstr));
+ if (nf == NULL) return NULL;
+ f->fstr = nf;
+ return f;
+}
+
+int compcert_fscanf(compcert_FILE * f, const char * s, ...)
+{
+ va_list ap;
+ int retcode;
+ va_start(ap, s);
+ retcode = vfscanf((FILE *)(f->fstr), s, ap);
+ va_end(ap);
+ return retcode;
+}
+
+int compcert_fseek(compcert_FILE * f, long p, int q)
+{
+ return fseek((FILE *)(f->fstr), p, q);
+}
+
+long compcert_ftell(compcert_FILE *f)
+{
+ return ftell((FILE *)(f->fstr));
+}
+
+size_t compcert_fwrite(const void * b, size_t p, size_t q, compcert_FILE * f)
+{
+ return fwrite(b, p, q, (FILE *)(f->fstr));
+}
+
+int compcert_getc(compcert_FILE * f)
+{
+ return getc((FILE *)(f->fstr));
+}
+
+int compcert_putc(int c , compcert_FILE * f)
+{
+ return putc(c, (FILE *)(f->fstr));
+}
+
+void compcert_rewind(compcert_FILE * f)
+{
+ rewind((FILE *)(f->fstr));
+}
+
+int compcert_ungetc(int c, compcert_FILE * f)
+{
+ return ungetc(c, (FILE *)(f->fstr));
+}
+
+int compcert_vfprintf(compcert_FILE * f, const char * s, va_list va)
+{
+ return vfprintf((FILE *)(f->fstr), s, va);
+}
diff --git a/runtime/stdio.h b/runtime/stdio.h
new file mode 100644
index 0000000..2442dcb
--- /dev/null
+++ b/runtime/stdio.h
@@ -0,0 +1,67 @@
+#ifndef _COMPCERT_STDIO_H
+#define _COMPCERT_STDIO_H
+
+#include "/usr/include/stdio.h"
+
+typedef struct compcert_FILE_ { void * fstr; } compcert_FILE;
+
+extern compcert_FILE * compcert_stdin;
+extern compcert_FILE * compcert_stdout;
+extern compcert_FILE * compcert_stderr;
+extern void compcert_clearerr(compcert_FILE *);
+extern int compcert_fclose(compcert_FILE *);
+extern int compcert_feof(compcert_FILE *);
+extern int compcert_ferror(compcert_FILE *);
+extern int compcert_fflush(compcert_FILE *);
+extern int compcert_fgetc(compcert_FILE *);
+extern char *compcert_fgets(char * , int, compcert_FILE *);
+extern compcert_FILE *compcert_fopen(const char * , const char * );
+extern int compcert_fprintf(compcert_FILE * , const char * , ...);
+extern int compcert_fputc(int, compcert_FILE *);
+extern int compcert_fputs(const char * , compcert_FILE * );
+extern size_t compcert_fread(void * , size_t, size_t, compcert_FILE * );
+extern compcert_FILE *compcert_freopen(const char * , const char * ,
+ compcert_FILE * );
+extern int compcert_fscanf(compcert_FILE * , const char * , ...);
+extern int compcert_fseek(compcert_FILE *, long, int);
+extern long compcert_ftell(compcert_FILE *);
+extern size_t compcert_fwrite(const void * , size_t, size_t, compcert_FILE * );
+extern int compcert_getc(compcert_FILE *);
+extern int compcert_putc(int, compcert_FILE *);
+extern void compcert_rewind(compcert_FILE *);
+extern int compcert_ungetc(int, compcert_FILE *);
+extern int compcert_vfprintf(compcert_FILE *, const char *, va_list);
+
+#ifndef _INSIDE_COMPCERT_COMPATIBILITY_LIBRARY
+#define FILE compcert_FILE
+#undef stdin
+#define stdin compcert_stdin
+#undef stdout
+#define stdout compcert_stdout
+#undef stderr
+#define stderr compcert_stderr
+#define clearerr compcert_clearerr
+#define fclose compcert_fclose
+#define feof compcert_feof
+#define ferror compcert_ferror
+#define fflush compcert_fflush
+#define fgetc compcert_fgetc
+#define fgets compcert_fgets
+#define fopen compcert_fopen
+#define fprintf compcert_fprintf
+#define fputc compcert_fputc
+#define fputs compcert_fputs
+#define fread compcert_fread
+#define freopen compcert_freopen
+#define fscanf compcert_fscanf
+#define fseek compcert_fseek
+#define ftell compcert_ftell
+#define fwrite compcert_fwrite
+#define getc compcert_getc
+#define putc compcert_putc
+#define rewind compcert_rewind
+#define ungetc compcert_ungetc
+#define vfprintf compcert_vfprintf
+#endif
+
+#endif
diff --git a/test/c/Makefile b/test/c/Makefile
index 8896934..3f4ea40 100644
--- a/test/c/Makefile
+++ b/test/c/Makefile
@@ -1,8 +1,7 @@
CCOMP=../../ccomp
-CCOMPFLAGS=-dump-c -I../lib
+CCOMPFLAGS=-stdlib ../../runtime -dclight -dasm
CC=gcc -arch ppc
-
CFLAGS=-O1 -Wall
LIBS=
@@ -20,11 +19,11 @@ all: $(PROGS:%=%.compcert)
all_gcc: $(PROGS:%=%.gcc)
-%.compcert: %.s
- $(CC) $(CFLAGS) -o $*.compcert $*.s ../lib/libcompcert.a $(LIBS)
+%.compcert: %.c $(CCOMP)
+ $(CCOMP) $(CCOMPFLAGS) -o $*.compcert $*.c $(LIBS)
%.s: %.c ../../ccomp
- $(CCOMP) $(CCOMPFLAGS) $*.c
+ $(CCOMP) $(CCOMPFLAGS) -S $*.c
%.gcc: %.c
$(CC) $(CFLAGS) -o $*.gcc $*.c $(LIBS)
diff --git a/test/c/knucleotide.c b/test/c/knucleotide.c
index 955af7f..f743892 100644
--- a/test/c/knucleotide.c
+++ b/test/c/knucleotide.c
@@ -8,11 +8,7 @@
http://cvs.alioth.debian.org/cgi-bin/cvsweb.cgi/shootout/bench/Include/?cvsroot=shootout
*/
-#ifdef __COMPCERT__
-#include <compcert_stdio.h>
-#else
#include <stdio.h>
-#endif
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
diff --git a/test/c/mandelbrot.c b/test/c/mandelbrot.c
index f4c0db1..93aa8ac 100644
--- a/test/c/mandelbrot.c
+++ b/test/c/mandelbrot.c
@@ -10,11 +10,7 @@
compile flags: -O3 -ffast-math -march=pentium4 -funroll-loops
*/
-#ifdef __COMPCERT__
-#include <compcert_stdio.h>
-#else
#include <stdio.h>
-#endif
#include <stdlib.h>
int main (int argc, char **argv)
diff --git a/test/cminor/Makefile b/test/cminor/Makefile
index 29ebf69..9d2dfdb 100644
--- a/test/cminor/Makefile
+++ b/test/cminor/Makefile
@@ -1,4 +1,5 @@
CCOMP=../../ccomp
+FLAGS=-S
CPP=cpp -P
CC=gcc
CFLAGS=-arch ppc -g
@@ -69,6 +70,11 @@ marksweep: marksweep.o maingc.o marksweepcheck.o
clean::
rm -f stopcopy
+switchtbl: switchtbl.o mainswitchtbl.o
+ $(CC) $(CFLAGS) -o switchtbl switchtbl.o mainswitchtbl.o
+clean::
+ rm -f switchtbl
+
.SUFFIXES:
.SUFFIXES: .cmp .cm .s .o .c .S
diff --git a/test/cminor/sha1.cmp b/test/cminor/sha1.cmp
index ca24544..31c4b17 100644
--- a/test/cminor/sha1.cmp
+++ b/test/cminor/sha1.cmp
@@ -54,7 +54,7 @@ extern "memset" : int -> int -> int -> void
"SHA1_transform"(ctx) : int -> void
{
- stack 320
+ stack 320;
var i, p, a, b, c, d, e, t;
/* Convert buffer data to 16 big-endian integers */
diff --git a/test/cminor/switchtbl.cm b/test/cminor/switchtbl.cm
new file mode 100644
index 0000000..07bda7e
--- /dev/null
+++ b/test/cminor/switchtbl.cm
@@ -0,0 +1,16 @@
+"f"(x): int -> int
+{
+ match (x) {
+ case 0: return 00;
+ case 1: return 11;
+ case 2: return 22;
+ case 3: return 33;
+ case 4: return 44;
+ case 5: return 55;
+ case 6: return 66;
+ case 7: return 77;
+ case 8: return 88;
+ case 9: return 99;
+}
+}
+
diff --git a/test/harness/mainlists.c b/test/harness/mainlists.c
index ef11f6e..281b919 100644
--- a/test/harness/mainlists.c
+++ b/test/harness/mainlists.c
@@ -2,11 +2,6 @@
#include <stddef.h>
#include <stdlib.h>
-void * compcert_alloc(int sz)
-{
- return malloc(sz);
-}
-
struct cons { int hd; struct cons * tl; };
typedef struct cons * list;
diff --git a/test/harness/mainswitchtbl.c b/test/harness/mainswitchtbl.c
new file mode 100644
index 0000000..24ba17e
--- /dev/null
+++ b/test/harness/mainswitchtbl.c
@@ -0,0 +1,11 @@
+#include <stdlib.h>
+#include <stdio.h>
+
+extern int f(int);
+
+int main(int argc, char ** argv)
+{
+ int i;
+ for (i = 0; i < 10; i++) printf("%2d -> %2d\n", i, f(i));
+ return 0;
+}