aboutsummaryrefslogtreecommitdiffstats
path: root/powerpc
diff options
context:
space:
mode:
authorYann Herklotz <git@yannherklotz.com>2021-09-17 18:28:55 +0100
committerYann Herklotz <git@yannherklotz.com>2021-09-17 18:28:55 +0100
commita1c401a4eba5fc9fcf42933f70005ecb679a4c1c (patch)
tree26637fca5d1da9b3d049234721d593a60b03a6d3 /powerpc
parentc49caca4b5f0239b43610fbfe012d6ba0211b364 (diff)
parent1daf96cdca4d828c333cea5c9a314ef861342984 (diff)
downloadcompcert-a1c401a4eba5fc9fcf42933f70005ecb679a4c1c.tar.gz
compcert-a1c401a4eba5fc9fcf42933f70005ecb679a4c1c.zip
Merge branch 'master' into dev/michalisdev/michalis
Diffstat (limited to 'powerpc')
-rw-r--r--powerpc/Archi.v9
-rw-r--r--powerpc/Asm.v15
-rw-r--r--powerpc/AsmToJSON.ml3
-rw-r--r--powerpc/Asmexpand.ml199
-rw-r--r--powerpc/Asmgen.v186
-rw-r--r--powerpc/Asmgenproof.v51
-rw-r--r--powerpc/Asmgenproof1.v347
-rw-r--r--powerpc/Builtins1.v9
-rw-r--r--powerpc/CBuiltins.ml9
-rw-r--r--powerpc/ConstpropOpproof.v2
-rw-r--r--powerpc/Conventions1.v49
-rw-r--r--powerpc/Machregs.v2
-rw-r--r--powerpc/NeedOp.v6
-rw-r--r--powerpc/Op.v18
-rw-r--r--powerpc/SelectLongproof.v6
-rw-r--r--powerpc/SelectOp.vp8
-rw-r--r--powerpc/SelectOpproof.v28
-rw-r--r--powerpc/Stacklayout.v36
-rw-r--r--powerpc/TargetPrinter.ml32
-rw-r--r--powerpc/ValueAOp.v3
-rw-r--r--powerpc/extractionMachdep.v10
21 files changed, 544 insertions, 484 deletions
diff --git a/powerpc/Archi.v b/powerpc/Archi.v
index ae10c54c..28859051 100644
--- a/powerpc/Archi.v
+++ b/powerpc/Archi.v
@@ -7,10 +7,11 @@
(* *)
(* Copyright Institut National de Recherche en Informatique et en *)
(* Automatique. All rights reserved. This file is distributed *)
-(* under the terms of the GNU General Public License as published by *)
-(* the Free Software Foundation, either version 2 of the License, or *)
-(* (at your option) any later version. This file is also distributed *)
-(* under the terms of the INRIA Non-Commercial License Agreement. *)
+(* under the terms of the GNU Lesser General Public License as *)
+(* published by the Free Software Foundation, either version 2.1 of *)
+(* the License, or (at your option) any later version. *)
+(* This file is also distributed under the terms of the *)
+(* INRIA Non-Commercial License Agreement. *)
(* *)
(* *********************************************************************)
diff --git a/powerpc/Asm.v b/powerpc/Asm.v
index 4fb38ff8..6b1f2232 100644
--- a/powerpc/Asm.v
+++ b/powerpc/Asm.v
@@ -200,12 +200,9 @@ Inductive instruction : Type :=
| Pfadd: freg -> freg -> freg -> instruction (**r float addition *)
| Pfadds: freg -> freg -> freg -> instruction (**r float addition *)
| Pfcmpu: freg -> freg -> instruction (**r float comparison *)
- | Pfcfi: freg -> ireg -> instruction (**r signed-int-to-float conversion (pseudo, PPC64) *)
| Pfcfl: freg -> ireg -> instruction (**r signed-long-to-float conversion (pseudo, PPC64) *)
- | Pfcfiu: freg -> ireg -> instruction (**r unsigned-int-to-float conversion (pseudo, PPC64) *)
| Pfcfid: freg -> freg -> instruction (**r signed-long-to-float conversion (PPC64) *)
| Pfcti: ireg -> freg -> instruction (**r float-to-signed-int conversion, round towards 0 (pseudo) *)
- | Pfctiu: ireg -> freg -> instruction (**r float-to-unsigned-int conversion, round towards 0 (pseudo, PPC64) *)
| Pfctid: ireg -> freg -> instruction (**r float-to-signed-int conversion, round towards 0 (pseudo, PPC64) *)
| Pfctidz: freg -> freg -> instruction (**r float-to-signed-long conversion, round towards 0 (PPC64) *)
| Pfctiw: freg -> freg -> instruction (**r float-to-signed-int conversion, round by default *)
@@ -541,6 +538,8 @@ Axiom small_data_area_addressing:
Parameter symbol_is_rel_data: ident -> ptrofs -> bool.
+Parameter symbol_is_aligned: ident -> Z -> bool.
+
(** Armed with the [low_half] and [high_half] functions,
we can define the evaluation of a symbolic constant.
Note that for [const_high], integer constants
@@ -825,16 +824,10 @@ Definition exec_instr (f: function) (i: instruction) (rs: regset) (m: mem) : out
Next (nextinstr (rs#rd <- (Val.addfs rs#r1 rs#r2))) m
| Pfcmpu r1 r2 =>
Next (nextinstr (compare_float rs rs#r1 rs#r2)) m
- | Pfcfi rd r1 =>
- Next (nextinstr (rs#rd <- (Val.maketotal (Val.floatofint rs#r1)))) m
| Pfcfl rd r1 =>
Next (nextinstr (rs#rd <- (Val.maketotal (Val.floatoflong rs#r1)))) m
- | Pfcfiu rd r1 =>
- Next (nextinstr (rs#rd <- (Val.maketotal (Val.floatofintu rs#r1)))) m
| Pfcti rd r1 =>
Next (nextinstr (rs#FPR13 <- Vundef #rd <- (Val.maketotal (Val.intoffloat rs#r1)))) m
- | Pfctiu rd r1 =>
- Next (nextinstr (rs#FPR13 <- Vundef #rd <- (Val.maketotal (Val.intuoffloat rs#r1)))) m
| Pfctid rd r1 =>
Next (nextinstr (rs#FPR13 <- Vundef #rd <- (Val.maketotal (Val.longoffloat rs#r1)))) m
| Pfdiv rd r1 r2 =>
@@ -1204,7 +1197,7 @@ Inductive step: state -> trace -> state -> Prop :=
external_call ef ge vargs m t vres m' ->
rs' = nextinstr
(set_res res vres
- (undef_regs (map preg_of (destroyed_by_builtin ef)) rs)) ->
+ (undef_regs (IR GPR0 :: map preg_of (destroyed_by_builtin ef)) rs)) ->
step (State rs m) t (State rs' m')
| exec_step_external:
forall b ef args res rs m t rs' m',
@@ -1285,7 +1278,7 @@ Ltac Equalities :=
split. auto. intros. destruct B; auto. subst. auto.
(* trace length *)
red; intros. inv H; simpl.
- omega.
+ lia.
eapply external_call_trace_length; eauto.
eapply external_call_trace_length; eauto.
(* initial states *)
diff --git a/powerpc/AsmToJSON.ml b/powerpc/AsmToJSON.ml
index f4d4285a..09cfc28d 100644
--- a/powerpc/AsmToJSON.ml
+++ b/powerpc/AsmToJSON.ml
@@ -198,12 +198,9 @@ let pp_instructions pp ic =
| Pfadd (fr1,fr2,fr3) -> instruction pp "Pfadd" [Freg fr1; Freg fr2; Freg fr3]
| Pfadds (fr1,fr2,fr3) -> instruction pp "Pfadds" [Freg fr1; Freg fr2; Freg fr3]
| Pfcmpu (fr1,fr2) -> instruction pp "Pfcmpu" [Freg fr1; Freg fr2]
- | Pfcfi (ir,fr)
| Pfcfl (ir,fr) -> assert false (* Should not occur *)
| Pfcfid (fr1,fr2) -> instruction pp "Pfcfid" [Freg fr1; Freg fr2]
- | Pfcfiu _ (* Should not occur *)
| Pfcti _ (* Should not occur *)
- | Pfctiu _ (* Should not occur *)
| Pfctid _ -> assert false (* Should not occur *)
| Pfctidz (fr1,fr2) -> instruction pp "Pfctidz" [Freg fr1; Freg fr2]
| Pfctiw (fr1,fr2) -> instruction pp "Pfctiw" [Freg fr1; Freg fr2]
diff --git a/powerpc/Asmexpand.ml b/powerpc/Asmexpand.ml
index d8cbd94e..7efa80a6 100644
--- a/powerpc/Asmexpand.ml
+++ b/powerpc/Asmexpand.ml
@@ -58,6 +58,20 @@ let emit_loadimm r n =
let emit_addimm rd rs n =
List.iter emit (Asmgen.addimm rd rs n [])
+let emit_aindexed mk1 mk2 unaligned r1 temp ofs =
+ List.iter emit (Asmgen.aindexed mk1 mk2 unaligned r1 temp ofs [])
+
+let emit_aindexed2 mk r1 r2 =
+ List.iter emit (Asmgen.aindexed2 mk r1 r2 [])
+
+let emit_aglobal mk1 mk2 unaligned temp symb ofs =
+ List.iter emit (Asmgen.aglobal mk1 mk2 unaligned temp symb ofs [])
+
+let emit_abased mk1 mk2 unaligned r1 temp symb ofs =
+ List.iter emit (Asmgen.abased mk1 mk2 unaligned r1 temp symb ofs [])
+
+let emit_ainstack mk1 mk2 unaligned temp ofs =
+ List.iter emit (Asmgen.ainstack mk1 mk2 unaligned temp ofs [])
(* Numbering of bits in the CR register *)
let num_crbit = function
@@ -175,52 +189,23 @@ let expand_builtin_memcpy sz al args =
(* Handling of volatile reads and writes *)
let expand_volatile_access
- (mk1: ireg -> constant -> unit)
- (mk2: ireg -> ireg -> unit)
+ (mk1: constant -> ireg -> instruction list -> instruction list)
+ (mk2: ireg -> ireg -> instruction list -> instruction list)
+ ?(ofs_unaligned = true)
addr temp =
match addr with
| BA(IR r) ->
- mk1 r (Cint _0)
+ List.iter emit (mk1 (Cint _0) r [])
| BA_addrstack ofs ->
- if offset_in_range ofs then
- mk1 GPR1 (Cint ofs)
- else begin
- emit (Paddis(temp, GPR1, Cint (Asmgen.high_s ofs)));
- mk1 temp (Cint (Asmgen.low_s ofs))
- end
+ emit_ainstack mk1 mk2 ofs_unaligned temp ofs
| BA_addrglobal(id, ofs) ->
- if symbol_is_small_data id ofs then
- mk1 GPR0 (Csymbol_sda(id, ofs))
- else if symbol_is_rel_data id ofs then begin
- emit (Paddis(temp, GPR0, Csymbol_rel_high(id, ofs)));
- emit (Paddi(temp, temp, Csymbol_rel_low(id, ofs)));
- mk1 temp (Cint _0)
- end else begin
- emit (Paddis(temp, GPR0, Csymbol_high(id, ofs)));
- mk1 temp (Csymbol_low(id, ofs))
- end
+ emit_aglobal mk1 mk2 ofs_unaligned temp id ofs
| BA_addptr(BA(IR r), BA_int n) ->
- if offset_in_range n then
- mk1 r (Cint n)
- else begin
- emit (Paddis(temp, r, Cint (Asmgen.high_s n)));
- mk1 temp (Cint (Asmgen.low_s n))
- end
+ emit_aindexed mk1 mk2 ofs_unaligned r temp n
| BA_addptr(BA_addrglobal(id, ofs), BA(IR r)) ->
- if symbol_is_small_data id ofs then begin
- emit (Paddi(GPR0, GPR0, Csymbol_sda(id, ofs)));
- mk2 r GPR0
- end else if symbol_is_rel_data id ofs then begin
- emit (Pmr(GPR0, r));
- emit (Paddis(temp, GPR0, Csymbol_rel_high(id, ofs)));
- emit (Paddi(temp, temp, Csymbol_rel_low(id, ofs)));
- mk2 temp GPR0
- end else begin
- emit (Paddis(temp, r, Csymbol_high(id, ofs)));
- mk1 temp (Csymbol_low(id, ofs))
- end
+ emit_abased mk1 mk2 ofs_unaligned r temp id ofs
| BA_addptr(BA(IR r1), BA(IR r2)) ->
- mk2 r1 r2
+ emit_aindexed2 mk2 r1 r2
| _ ->
assert false
@@ -233,68 +218,69 @@ let offset_constant cst delta =
Some (Csymbol_sda(id, Int.add ofs delta))
| _ -> None
-let expand_load_int64 hi lo base ofs_hi ofs_lo =
+let expand_load_int64 hi lo base ofs_hi ofs_lo k =
if hi <> base then begin
- emit (Plwz(hi, ofs_hi, base));
- emit (Plwz(lo, ofs_lo, base))
+ Plwz(hi, ofs_hi, base) ::
+ Plwz(lo, ofs_lo, base) :: k
end else begin
- emit (Plwz(lo, ofs_lo, base));
- emit (Plwz(hi, ofs_hi, base))
+ Plwz(lo, ofs_lo, base) ::
+ Plwz(hi, ofs_hi, base) :: k
end
let expand_builtin_vload_1 chunk addr res =
match chunk, res with
| Mint8unsigned, BR(IR res) ->
expand_volatile_access
- (fun r c -> emit (Plbz(res, c, r)))
- (fun r1 r2 -> emit (Plbzx(res, r1, r2)))
+ (fun c r k -> Plbz(res, c, r) :: k)
+ (fun r1 r2 k -> Plbzx(res, r1, r2) :: k)
addr GPR11
| Mint8signed, BR(IR res) ->
expand_volatile_access
- (fun r c -> emit (Plbz(res, c, r)); emit (Pextsb(res, res)))
- (fun r1 r2 -> emit (Plbzx(res, r1, r2)); emit (Pextsb(res, res)))
+ (fun c r k-> Plbz(res, c, r) :: Pextsb(res, res) :: k)
+ (fun r1 r2 k -> Plbzx(res, r1, r2) :: Pextsb(res, res) :: k)
addr GPR11
| Mint16unsigned, BR(IR res) ->
expand_volatile_access
- (fun r c -> emit (Plhz(res, c, r)))
- (fun r1 r2 -> emit (Plhzx(res, r1, r2)))
+ (fun c r k -> Plhz(res, c, r) :: k)
+ (fun r1 r2 k -> Plhzx(res, r1, r2) :: k)
addr GPR11
| Mint16signed, BR(IR res) ->
expand_volatile_access
- (fun r c -> emit (Plha(res, c, r)))
- (fun r1 r2 -> emit (Plhax(res, r1, r2)))
+ (fun c r k-> Plha(res, c, r) :: k)
+ (fun r1 r2 k -> Plhax(res, r1, r2) :: k)
addr GPR11
| (Mint32 | Many32), BR(IR res) ->
expand_volatile_access
- (fun r c -> emit (Plwz(res, c, r)))
- (fun r1 r2 -> emit (Plwzx(res, r1, r2)))
+ (fun c r k-> Plwz(res, c, r) :: k)
+ (fun r1 r2 k -> Plwzx(res, r1, r2) :: k)
addr GPR11
| Mfloat32, BR(FR res) ->
expand_volatile_access
- (fun r c -> emit (Plfs(res, c, r)))
- (fun r1 r2 -> emit (Plfsx(res, r1, r2)))
+ (fun c r k-> Plfs(res, c, r) :: k)
+ (fun r1 r2 k -> Plfsx(res, r1, r2) :: k)
addr GPR11
| (Mfloat64 | Many64), BR(FR res) ->
expand_volatile_access
- (fun r c -> emit (Plfd(res, c, r)))
- (fun r1 r2 -> emit (Plfdx(res, r1, r2)))
+ (fun c r k-> Plfd(res, c, r) :: k)
+ (fun r1 r2 k -> Plfdx(res, r1, r2) :: k)
addr GPR11
| (Mint64 | Many64), BR(IR res) ->
expand_volatile_access
- (fun r c -> emit (Pld(res, c, r)))
- (fun r1 r2 -> emit (Pldx(res, r1, r2)))
+ (fun c r k-> Pld(res, c, r) :: k)
+ (fun r1 r2 k -> Pldx(res, r1, r2) :: k)
+ ~ofs_unaligned:false
addr GPR11
| Mint64, BR_splitlong(BR(IR hi), BR(IR lo)) ->
expand_volatile_access
- (fun r c ->
+ (fun c r k->
match offset_constant c _4 with
- | Some c' -> expand_load_int64 hi lo r c c'
+ | Some c' -> expand_load_int64 hi lo r c c' k
| None ->
- emit (Paddi(GPR11, r, c));
- expand_load_int64 hi lo GPR11 (Cint _0) (Cint _4))
- (fun r1 r2 ->
- emit (Padd(GPR11, r1, r2));
- expand_load_int64 hi lo GPR11 (Cint _0) (Cint _4))
+ Paddi(GPR11, r, c) ::
+ expand_load_int64 hi lo GPR11 (Cint _0) (Cint _4) k)
+ (fun r1 r2 k ->
+ Padd(GPR11, r1, r2) ::
+ expand_load_int64 hi lo GPR11 (Cint _0) (Cint _4) k)
addr GPR11
| _, _ ->
assert false
@@ -310,54 +296,55 @@ let temp_for_vstore src =
else if not (List.mem (IR GPR12) rl) then GPR12
else GPR10
-let expand_store_int64 hi lo base ofs_hi ofs_lo =
- emit (Pstw(hi, ofs_hi, base));
- emit (Pstw(lo, ofs_lo, base))
+let expand_store_int64 hi lo base ofs_hi ofs_lo k =
+ Pstw(hi, ofs_hi, base) ::
+ Pstw(lo, ofs_lo, base) :: k
let expand_builtin_vstore_1 chunk addr src =
let temp = temp_for_vstore src in
match chunk, src with
| (Mint8signed | Mint8unsigned), BA(IR src) ->
expand_volatile_access
- (fun r c -> emit (Pstb(src, c, r)))
- (fun r1 r2 -> emit (Pstbx(src, r1, r2)))
+ (fun c r k-> Pstb(src, c, r) :: k)
+ (fun r1 r2 k -> Pstbx(src, r1, r2) :: k)
addr temp
| (Mint16signed | Mint16unsigned), BA(IR src) ->
expand_volatile_access
- (fun r c -> emit (Psth(src, c, r)))
- (fun r1 r2 -> emit (Psthx(src, r1, r2)))
+ (fun c r k-> Psth(src, c, r) :: k)
+ (fun r1 r2 k -> Psthx(src, r1, r2) :: k)
addr temp
| (Mint32 | Many32), BA(IR src) ->
expand_volatile_access
- (fun r c -> emit (Pstw(src, c, r)))
- (fun r1 r2 -> emit (Pstwx(src, r1, r2)))
+ (fun c r k-> Pstw(src, c, r) :: k)
+ (fun r1 r2 k -> Pstwx(src, r1, r2) :: k)
addr temp
| Mfloat32, BA(FR src) ->
expand_volatile_access
- (fun r c -> emit (Pstfs(src, c, r)))
- (fun r1 r2 -> emit (Pstfsx(src, r1, r2)))
+ (fun c r k-> Pstfs(src, c, r) :: k)
+ (fun r1 r2 k -> Pstfsx(src, r1, r2) :: k)
addr temp
| (Mfloat64 | Many64), BA(FR src) ->
expand_volatile_access
- (fun r c -> emit (Pstfd(src, c, r)))
- (fun r1 r2 -> emit (Pstfdx(src, r1, r2)))
+ (fun c r k-> Pstfd(src, c, r) :: k)
+ (fun r1 r2 k -> Pstfdx(src, r1, r2) :: k)
addr temp
| (Mint64 | Many64), BA(IR src) ->
expand_volatile_access
- (fun r c -> emit (Pstd(src, c, r)))
- (fun r1 r2 -> emit (Pstdx(src, r1, r2)))
+ (fun c r k-> Pstd(src, c, r) :: k)
+ (fun r1 r2 k -> Pstdx(src, r1, r2) :: k)
+ ~ofs_unaligned:false
addr temp
| Mint64, BA_splitlong(BA(IR hi), BA(IR lo)) ->
expand_volatile_access
- (fun r c ->
+ (fun c r k ->
match offset_constant c _4 with
- | Some c' -> expand_store_int64 hi lo r c c'
+ | Some c' -> expand_store_int64 hi lo r c c' k
| None ->
- emit (Paddi(temp, r, c));
- expand_store_int64 hi lo temp (Cint _0) (Cint _4))
- (fun r1 r2 ->
- emit (Padd(temp, r1, r2));
- expand_store_int64 hi lo temp (Cint _0) (Cint _4))
+ Paddi(temp, r, c) ::
+ expand_store_int64 hi lo temp (Cint _0) (Cint _4) k)
+ (fun r1 r2 k ->
+ Padd(temp, r1, r2) ::
+ expand_store_int64 hi lo temp (Cint _0) (Cint _4) k)
addr temp
| _, _ ->
assert false
@@ -388,8 +375,9 @@ let rec next_arg_locations ir fr ofs = function
then next_arg_locations ir (fr + 1) ofs l
else next_arg_locations ir fr (align ofs 8 + 8) l
| Tlong :: l ->
- if ir < 7
- then next_arg_locations (align ir 2 + 2) fr ofs l
+ let ir = align ir 2 in
+ if ir < 8
+ then next_arg_locations (ir + 2) fr ofs l
else next_arg_locations ir fr (align ofs 8 + 8) l
let expand_builtin_va_start r =
@@ -763,6 +751,9 @@ let expand_builtin_inline name args res =
(* no operation *)
| "__builtin_nop", [], _ ->
emit (Pori (GPR0, GPR0, Cint _0))
+ (* Optimization hint *)
+ | "__builtin_unreachable", [], _ ->
+ ()
(* atomic operations *)
| "__builtin_atomic_exchange", [BA (IR a1); BA (IR a2); BA (IR a3)],_ ->
(* Register constraints imposed by Machregs.v *)
@@ -830,7 +821,7 @@ let expand_builtin_inline name args res =
function is unprototyped. *)
let set_cr6 sg =
- if sg.sig_cc.cc_vararg || sg.sig_cc.cc_unproto then begin
+ if (sg.sig_cc.cc_vararg <> None) || sg.sig_cc.cc_unproto then begin
if List.exists (function Tfloat | Tsingle -> true | _ -> false) sg.sig_args
then emit (Pcreqv(CRbit_6, CRbit_6, CRbit_6))
else emit (Pcrxor(CRbit_6, CRbit_6, CRbit_6))
@@ -875,15 +866,6 @@ let expand_instruction instr =
emit (Paddi(GPR1, GPR1, Cint(coqint_of_camlint sz)))
else
emit (Plwz(GPR1, Cint ofs, GPR1))
- | Pfcfi(r1, r2) ->
- assert (Archi.ppc64);
- emit (Pextsw(GPR0, r2));
- emit (Pstdu(GPR0, Cint _m8, GPR1));
- emit (Pcfi_adjust _8);
- emit (Plfd(r1, Cint _0, GPR1));
- emit (Pfcfid(r1, r1));
- emit (Paddi(GPR1, GPR1, Cint _8));
- emit (Pcfi_adjust _m8)
| Pfcfl(r1, r2) ->
assert (Archi.ppc64);
emit (Pstdu(r2, Cint _m8, GPR1));
@@ -892,15 +874,6 @@ let expand_instruction instr =
emit (Pfcfid(r1, r1));
emit (Paddi(GPR1, GPR1, Cint _8));
emit (Pcfi_adjust _m8)
- | Pfcfiu(r1, r2) ->
- assert (Archi.ppc64);
- emit (Prldicl(GPR0, r2, _0, _32));
- emit (Pstdu(GPR0, Cint _m8, GPR1));
- emit (Pcfi_adjust _8);
- emit (Plfd(r1, Cint _0, GPR1));
- emit (Pfcfid(r1, r1));
- emit (Paddi(GPR1, GPR1, Cint _8));
- emit (Pcfi_adjust _m8)
| Pfcti(r1, r2) ->
emit (Pfctiwz(FPR13, r2));
emit (Pstfdu(FPR13, Cint _m8, GPR1));
@@ -908,14 +881,6 @@ let expand_instruction instr =
emit (Plwz(r1, Cint _4, GPR1));
emit (Paddi(GPR1, GPR1, Cint _8));
emit (Pcfi_adjust _m8)
- | Pfctiu(r1, r2) ->
- assert (Archi.ppc64);
- emit (Pfctidz(FPR13, r2));
- emit (Pstfdu(FPR13, Cint _m8, GPR1));
- emit (Pcfi_adjust _8);
- emit (Plwz(r1, Cint _4, GPR1));
- emit (Paddi(GPR1, GPR1, Cint _8));
- emit (Pcfi_adjust _m8)
| Pfctid(r1, r2) ->
assert (Archi.ppc64);
emit (Pfctidz(FPR13, r2));
diff --git a/powerpc/Asmgen.v b/powerpc/Asmgen.v
index a686414a..7b6ac9af 100644
--- a/powerpc/Asmgen.v
+++ b/powerpc/Asmgen.v
@@ -190,36 +190,38 @@ Definition rolm64 (r1 r2: ireg) (amount: int) (mask: int64) (k: code) :=
(** Accessing slots in the stack frame. *)
+(* For 64 bit load and store the offset needs to be a multiple of word size *)
Definition accessind {A: Type}
(instr1: A -> constant -> ireg -> instruction)
(instr2: A -> ireg -> ireg -> instruction)
+ (unaligned : bool)
(base: ireg) (ofs: ptrofs) (r: A) (k: code) :=
let ofs := Ptrofs.to_int ofs in
- if Int.eq (high_s ofs) Int.zero
+ if Int.eq (high_s ofs) Int.zero && (unaligned || (Int.eq (Int.mods ofs (Int.repr 4)) Int.zero))
then instr1 r (Cint ofs) base :: k
else loadimm GPR0 ofs (instr2 r base GPR0 :: k).
Definition loadind (base: ireg) (ofs: ptrofs) (ty: typ) (dst: mreg) (k: code) :=
match ty, preg_of dst with
- | Tint, IR r => OK(accessind Plwz Plwzx base ofs r k)
- | Tany32, IR r => OK(accessind Plwz_a Plwzx_a base ofs r k)
- | Tsingle, FR r => OK(accessind Plfs Plfsx base ofs r k)
- | Tlong, IR r => OK(accessind Pld Pldx base ofs r k)
- | Tfloat, FR r => OK(accessind Plfd Plfdx base ofs r k)
- | Tany64, IR r => OK(accessind Pld_a Pldx_a base ofs r k)
- | Tany64, FR r => OK(accessind Plfd_a Plfdx_a base ofs r k)
+ | Tint, IR r => OK(accessind Plwz Plwzx true base ofs r k)
+ | Tany32, IR r => OK(accessind Plwz_a Plwzx_a true base ofs r k)
+ | Tsingle, FR r => OK(accessind Plfs Plfsx true base ofs r k)
+ | Tlong, IR r => OK(accessind Pld Pldx false base ofs r k)
+ | Tfloat, FR r => OK(accessind Plfd Plfdx true base ofs r k)
+ | Tany64, IR r => OK(accessind Pld_a Pldx_a false base ofs r k)
+ | Tany64, FR r => OK(accessind Plfd_a Plfdx_a true base ofs r k)
| _, _ => Error (msg "Asmgen.loadind")
end.
Definition storeind (src: mreg) (base: ireg) (ofs: ptrofs) (ty: typ) (k: code) :=
match ty, preg_of src with
- | Tint, IR r => OK(accessind Pstw Pstwx base ofs r k)
- | Tany32, IR r => OK(accessind Pstw_a Pstwx_a base ofs r k)
- | Tsingle, FR r => OK(accessind Pstfs Pstfsx base ofs r k)
- | Tlong, IR r => OK(accessind Pstd Pstdx base ofs r k)
- | Tfloat, FR r => OK(accessind Pstfd Pstfdx base ofs r k)
- | Tany64, IR r => OK(accessind Pstd_a Pstdx_a base ofs r k)
- | Tany64, FR r => OK(accessind Pstfd_a Pstfdx_a base ofs r k)
+ | Tint, IR r => OK(accessind Pstw Pstwx true base ofs r k)
+ | Tany32, IR r => OK(accessind Pstw_a Pstwx_a true base ofs r k)
+ | Tsingle, FR r => OK(accessind Pstfs Pstfsx true base ofs r k)
+ | Tlong, IR r => OK(accessind Pstd Pstdx false base ofs r k)
+ | Tfloat, FR r => OK(accessind Pstfd Pstfdx true base ofs r k)
+ | Tany64, IR r => OK(accessind Pstd_a Pstdx_a false base ofs r k)
+ | Tany64, FR r => OK(accessind Pstfd_a Pstfdx_a true base ofs r k)
| _, _ => Error (msg "Asmgen.storeind")
end.
@@ -611,15 +613,6 @@ Definition transl_op
| Ointoffloat, a1 :: nil =>
do r1 <- freg_of a1; do r <- ireg_of res;
OK (Pfcti r r1 :: k)
- | Ointuoffloat, a1 :: nil =>
- do r1 <- freg_of a1; do r <- ireg_of res;
- OK (Pfctiu r r1 :: k)
- | Ofloatofint, a1 :: nil =>
- do r1 <- ireg_of a1; do r <- freg_of res;
- OK (Pfcfi r r1 :: k)
- | Ofloatofintu, a1 :: nil =>
- do r1 <- ireg_of a1; do r <- freg_of res;
- OK (Pfcfiu r r1 :: k)
| Ofloatofwords, a1 :: a2 :: nil =>
do r1 <- ireg_of a1; do r2 <- ireg_of a2; do r <- freg_of res;
OK (Pfmake r r1 r2 :: k)
@@ -733,52 +726,107 @@ Definition transl_op
Definition int_temp_for (r: mreg) :=
if mreg_eq r R12 then GPR11 else GPR12.
+Definition symbol_ofs_word_aligned symb ofs :=
+ let ofs := Ptrofs.to_int ofs in
+ symbol_is_aligned symb 4 && (Int.eq (Int.mods ofs (Int.repr 4)) Int.zero).
+
+Definition aindexed
+ (mk1: constant -> ireg -> code -> code)
+ (mk2: ireg -> ireg -> code -> code)
+ (unaligned : bool) (r1 temp: ireg) (ofs: int) (k: code) :=
+ if unaligned || Int.eq (Int.mods ofs (Int.repr 4)) Int.zero then
+ if Int.eq (high_s ofs) Int.zero then
+ mk1 (Cint ofs) r1 k
+ else
+ Paddis temp r1 (Cint (high_s ofs)) ::
+ mk1 (Cint (low_s ofs)) temp k
+ else
+ (loadimm GPR0 ofs (mk2 r1 GPR0 k)).
+
+Definition aindexed2
+ (mk: ireg -> ireg -> code -> code)
+ (r1 r2: ireg) (k: code) :=
+ mk r1 r2 k.
+
+Definition aglobal
+ (mk1: constant -> ireg -> code -> code)
+ (mk2: ireg -> ireg -> code -> code)
+ (unaligned : bool) (temp: ireg)
+ symb ofs k :=
+ if symbol_is_small_data symb ofs then
+ if unaligned || symbol_ofs_word_aligned symb ofs then
+ mk1 (Csymbol_sda symb ofs) GPR0 k
+ else
+ Paddi temp GPR0 (Csymbol_sda symb ofs) ::
+ mk1 (Cint Int.zero) temp k
+ else if symbol_is_rel_data symb ofs then
+ Paddis temp GPR0 (Csymbol_rel_high symb ofs) ::
+ Paddi temp temp (Csymbol_rel_low symb ofs) ::
+ mk1 (Cint Int.zero) temp k
+ else if unaligned || symbol_ofs_word_aligned symb ofs then
+ Paddis temp GPR0 (Csymbol_high symb ofs) ::
+ mk1 (Csymbol_low symb ofs) temp k
+ else
+ Paddis temp GPR0 (Csymbol_high symb ofs) ::
+ Paddi temp temp (Csymbol_low symb ofs) ::
+ mk1 (Cint Int.zero) temp k.
+
+Definition abased
+ (mk1: constant -> ireg -> code -> code)
+ (mk2: ireg -> ireg -> code -> code)
+ (unaligned : bool) (r1 temp: ireg)
+ symb ofs k :=
+ if symbol_is_small_data symb ofs then
+ Paddi GPR0 GPR0 (Csymbol_sda symb ofs) ::
+ mk2 r1 GPR0 k
+ else if symbol_is_rel_data symb ofs then
+ Pmr GPR0 r1 ::
+ Paddis temp GPR0 (Csymbol_rel_high symb ofs) ::
+ Paddi temp temp (Csymbol_rel_low symb ofs) ::
+ mk2 temp GPR0 k
+ else if unaligned || symbol_ofs_word_aligned symb ofs then
+ Paddis temp r1 (Csymbol_high symb ofs) ::
+ mk1 (Csymbol_low symb ofs) temp k
+ else
+ Pmr GPR0 r1 ::
+ Paddis temp GPR0 (Csymbol_high symb ofs) ::
+ Paddi temp temp (Csymbol_low symb ofs) ::
+ mk2 temp GPR0 k.
+
+Definition ainstack
+ (mk1 : constant -> ireg -> code -> code)
+ (mk2 : ireg -> ireg -> code -> code)
+ (unaligned : bool) (temp: ireg) ofs k :=
+ if unaligned || Int.eq (Int.mods ofs (Int.repr 4)) Int.zero then
+ if Int.eq (high_s ofs) Int.zero then
+ mk1 (Cint ofs) GPR1 k
+ else
+ Paddis temp GPR1 (Cint (high_s ofs)) ::
+ mk1 (Cint (low_s ofs)) temp k
+ else
+ addimm temp GPR1 ofs (mk1 (Cint Int.zero) temp k).
+
Definition transl_memory_access
(mk1: constant -> ireg -> instruction)
(mk2: ireg -> ireg -> instruction)
+ (unaligned : bool)
(addr: addressing) (args: list mreg)
(temp: ireg) (k: code) :=
match addr, args with
| Aindexed ofs, a1 :: nil =>
do r1 <- ireg_of a1;
- OK (if Int.eq (high_s ofs) Int.zero then
- mk1 (Cint ofs) r1 :: k
- else
- Paddis temp r1 (Cint (high_s ofs)) ::
- mk1 (Cint (low_s ofs)) temp :: k)
+ OK (aindexed (fun c r k => mk1 c r :: k) (fun r1 r2 k => mk2 r1 r2 :: k) unaligned r1 temp ofs k)
| Aindexed2, a1 :: a2 :: nil =>
do r1 <- ireg_of a1; do r2 <- ireg_of a2;
- OK (mk2 r1 r2 :: k)
+ OK (aindexed2 (fun r1 r2 k => mk2 r1 r2 :: k) r1 r2 k)
| Aglobal symb ofs, nil =>
- OK (if symbol_is_small_data symb ofs then
- mk1 (Csymbol_sda symb ofs) GPR0 :: k
- else if symbol_is_rel_data symb ofs then
- Paddis temp GPR0 (Csymbol_rel_high symb ofs) ::
- Paddi temp temp (Csymbol_rel_low symb ofs) ::
- mk1 (Cint Int.zero) temp :: k
- else
- Paddis temp GPR0 (Csymbol_high symb ofs) ::
- mk1 (Csymbol_low symb ofs) temp :: k)
+ OK (aglobal (fun c r k => mk1 c r :: k) (fun r1 r2 k => mk2 r1 r2 :: k) unaligned temp symb ofs k)
| Abased symb ofs, a1 :: nil =>
do r1 <- ireg_of a1;
- OK (if symbol_is_small_data symb ofs then
- Paddi GPR0 GPR0 (Csymbol_sda symb ofs) ::
- mk2 r1 GPR0 :: k
- else if symbol_is_rel_data symb ofs then
- Pmr GPR0 r1 ::
- Paddis temp GPR0 (Csymbol_rel_high symb ofs) ::
- Paddi temp temp (Csymbol_rel_low symb ofs) ::
- mk2 temp GPR0 :: k
- else
- Paddis temp r1 (Csymbol_high symb ofs) ::
- mk1 (Csymbol_low symb ofs) temp :: k)
+ OK (abased (fun c r k => mk1 c r :: k) (fun r1 r2 k => mk2 r1 r2 :: k) unaligned r1 temp symb ofs k)
| Ainstack ofs, nil =>
let ofs := Ptrofs.to_int ofs in
- OK (if Int.eq (high_s ofs) Int.zero then
- mk1 (Cint ofs) GPR1 :: k
- else
- Paddis temp GPR1 (Cint (high_s ofs)) ::
- mk1 (Cint (low_s ofs)) temp :: k)
+ OK (ainstack (fun c r k => mk1 c r :: k) (fun r1 r2 k => mk2 r1 r2 :: k) unaligned temp ofs k)
| _, _ =>
Error(msg "Asmgen.transl_memory_access")
end.
@@ -788,28 +836,28 @@ Definition transl_load (chunk: memory_chunk) (addr: addressing)
match chunk with
| Mint8signed =>
do r <- ireg_of dst;
- transl_memory_access (Plbz r) (Plbzx r) addr args GPR12 (Pextsb r r :: k)
+ transl_memory_access (Plbz r) (Plbzx r) true addr args GPR12 (Pextsb r r :: k)
| Mint8unsigned =>
do r <- ireg_of dst;
- transl_memory_access (Plbz r) (Plbzx r) addr args GPR12 k
+ transl_memory_access (Plbz r) (Plbzx r) true addr args GPR12 k
| Mint16signed =>
do r <- ireg_of dst;
- transl_memory_access (Plha r) (Plhax r) addr args GPR12 k
+ transl_memory_access (Plha r) (Plhax r) true addr args GPR12 k
| Mint16unsigned =>
do r <- ireg_of dst;
- transl_memory_access (Plhz r) (Plhzx r) addr args GPR12 k
+ transl_memory_access (Plhz r) (Plhzx r) true addr args GPR12 k
| Mint32 =>
do r <- ireg_of dst;
- transl_memory_access (Plwz r) (Plwzx r) addr args GPR12 k
+ transl_memory_access (Plwz r) (Plwzx r) true addr args GPR12 k
| Mint64 =>
do r <- ireg_of dst;
- transl_memory_access (Pld r) (Pldx r) addr args GPR12 k
+ transl_memory_access (Pld r) (Pldx r) false addr args GPR12 k
| Mfloat32 =>
do r <- freg_of dst;
- transl_memory_access (Plfs r) (Plfsx r) addr args GPR12 k
+ transl_memory_access (Plfs r) (Plfsx r) true addr args GPR12 k
| Mfloat64 =>
do r <- freg_of dst;
- transl_memory_access (Plfd r) (Plfdx r) addr args GPR12 k
+ transl_memory_access (Plfd r) (Plfdx r) true addr args GPR12 k
| _ =>
Error (msg "Asmgen.transl_load")
end.
@@ -820,22 +868,22 @@ Definition transl_store (chunk: memory_chunk) (addr: addressing)
match chunk with
| Mint8signed | Mint8unsigned =>
do r <- ireg_of src;
- transl_memory_access (Pstb r) (Pstbx r) addr args temp k
+ transl_memory_access (Pstb r) (Pstbx r) true addr args temp k
| Mint16signed | Mint16unsigned =>
do r <- ireg_of src;
- transl_memory_access (Psth r) (Psthx r) addr args temp k
+ transl_memory_access (Psth r) (Psthx r) true addr args temp k
| Mint32 =>
do r <- ireg_of src;
- transl_memory_access (Pstw r) (Pstwx r) addr args temp k
+ transl_memory_access (Pstw r) (Pstwx r) true addr args temp k
| Mint64 =>
do r <- ireg_of src;
- transl_memory_access (Pstd r) (Pstdx r) addr args temp k
+ transl_memory_access (Pstd r) (Pstdx r) false addr args temp k
| Mfloat32 =>
do r <- freg_of src;
- transl_memory_access (Pstfs r) (Pstfsx r) addr args temp k
+ transl_memory_access (Pstfs r) (Pstfsx r) true addr args temp k
| Mfloat64 =>
do r <- freg_of src;
- transl_memory_access (Pstfd r) (Pstfdx r) addr args temp k
+ transl_memory_access (Pstfd r) (Pstfdx r) true addr args temp k
| _ =>
Error (msg "Asmgen.transl_store")
end.
diff --git a/powerpc/Asmgenproof.v b/powerpc/Asmgenproof.v
index d653633c..85541118 100644
--- a/powerpc/Asmgenproof.v
+++ b/powerpc/Asmgenproof.v
@@ -69,7 +69,7 @@ Lemma transf_function_no_overflow:
transf_function f = OK tf -> list_length_z tf.(fn_code) <= Ptrofs.max_unsigned.
Proof.
intros. monadInv H. destruct (zlt Ptrofs.max_unsigned (list_length_z x.(fn_code))); inv EQ0.
- omega.
+ lia.
Qed.
Lemma exec_straight_exec:
@@ -205,10 +205,13 @@ Remark loadind_label:
forall base ofs ty dst k c,
loadind base ofs ty dst k = OK c -> tail_nolabel k c.
Proof.
- unfold loadind, accessind; intros. set (ofs' := Ptrofs.to_int ofs) in *.
+ unfold loadind, accessind ; intros.
+ set (ofs' := Ptrofs.to_int ofs) in *.
+ set (ofs_mod := Int.eq (Int.mods ofs' (Int.repr 4)) Int.zero) in *.
destruct ty; try discriminate;
destruct (preg_of dst); try discriminate;
destruct (Int.eq (high_s ofs') Int.zero);
+ destruct ofs_mod;
TailNoLabel; eapply tail_nolabel_trans; TailNoLabel.
Qed.
@@ -216,10 +219,13 @@ Remark storeind_label:
forall base ofs ty src k c,
storeind src base ofs ty k = OK c -> tail_nolabel k c.
Proof.
- unfold storeind, accessind; intros. set (ofs' := Ptrofs.to_int ofs) in *.
+ unfold storeind, accessind;
+ intros. set (ofs' := Ptrofs.to_int ofs) in *.
+ set (ofs_mod := Int.eq (Int.mods ofs' (Int.repr 4)) Int.zero) in *.
destruct ty; try discriminate;
destruct (preg_of src); try discriminate;
destruct (Int.eq (high_s ofs') Int.zero);
+ destruct ofs_mod;
TailNoLabel; eapply tail_nolabel_trans; TailNoLabel.
Qed.
@@ -298,17 +304,22 @@ Qed.
Remark transl_memory_access_label:
forall (mk1: constant -> ireg -> instruction) (mk2: ireg -> ireg -> instruction)
- addr args temp k c,
- transl_memory_access mk1 mk2 addr args temp k = OK c ->
+ unaligned addr args temp k c,
+ transl_memory_access mk1 mk2 unaligned addr args temp k = OK c ->
(forall c r, nolabel (mk1 c r)) ->
(forall r1 r2, nolabel (mk2 r1 r2)) ->
tail_nolabel k c.
Proof.
- unfold transl_memory_access; intros; destruct addr; TailNoLabel.
- destruct (Int.eq (high_s i) Int.zero); TailNoLabel.
- destruct (symbol_is_small_data i i0). TailNoLabel. destruct (symbol_is_rel_data i i0); TailNoLabel.
+ unfold transl_memory_access, aindexed, aindexed2, aglobal, abased, ainstack; intros; destruct addr; TailNoLabel.
+ destruct (unaligned || Int.eq (Int.mods i (Int.repr 4)) Int.zero). destruct (Int.eq (high_s i) Int.zero); TailNoLabel.
+ eapply tail_nolabel_trans. apply loadimm_label. TailNoLabel.
+ destruct (symbol_is_small_data i i0). destruct (unaligned || symbol_ofs_word_aligned i i0); TailNoLabel. destruct (symbol_is_rel_data i i0); TailNoLabel.
+ destruct (unaligned || symbol_ofs_word_aligned i i0); TailNoLabel.
destruct (symbol_is_small_data i i0). TailNoLabel. destruct (symbol_is_rel_data i i0); TailNoLabel.
+ destruct (unaligned || symbol_ofs_word_aligned i i0); TailNoLabel.
+ destruct (unaligned || Int.eq (Int.mods (Ptrofs.to_int i) (Int.repr 4)) Int.zero).
destruct (Int.eq (high_s (Ptrofs.to_int i)) Int.zero); TailNoLabel.
+ eapply tail_nolabel_trans. eapply addimm_label. TailNoLabel.
Qed.
Remark transl_epilogue_label:
@@ -401,8 +412,8 @@ Proof.
split. unfold goto_label. rewrite P. rewrite H1. auto.
split. rewrite Pregmap.gss. constructor; auto.
rewrite Ptrofs.unsigned_repr. replace (pos' - 0) with pos' in Q.
- auto. omega.
- generalize (transf_function_no_overflow _ _ H0). omega.
+ auto. lia.
+ generalize (transf_function_no_overflow _ _ H0). lia.
intros. apply Pregmap.gso; auto.
Qed.
@@ -781,16 +792,18 @@ Opaque loadind.
econstructor; eauto.
instantiate (2 := tf); instantiate (1 := x).
unfold nextinstr. rewrite Pregmap.gss.
- rewrite set_res_other. rewrite undef_regs_other_2.
+ rewrite set_res_other. simpl. rewrite undef_regs_other_2.
+ rewrite Pregmap.gso by auto with asmgen.
rewrite <- H1. simpl. econstructor; eauto.
eapply code_tail_next_int; eauto.
rewrite preg_notin_charact. intros. auto with asmgen.
auto with asmgen.
apply agree_nextinstr. eapply agree_set_res; auto.
- eapply agree_undef_regs; eauto. intros; apply undef_regs_other_2; auto.
+ eapply agree_undef_regs; eauto.
+ intros. simpl. rewrite undef_regs_other_2; auto. apply Pregmap.gso. auto with asmgen.
congruence.
intros. Simpl. rewrite set_res_other by auto.
- rewrite undef_regs_other_2; auto with asmgen.
+ simpl. rewrite undef_regs_other_2; auto with asmgen.
- (* Mgoto *)
assert (f0 = f) by congruence. subst f0.
@@ -924,14 +937,14 @@ Local Transparent destroyed_by_jumptable.
simpl const_low. rewrite ATLR. erewrite storev_offset_ptr by eexact P. auto. congruence.
auto. auto. auto.
left; exists (State rs5 m3'); split.
- eapply exec_straight_steps_1; eauto. omega. constructor.
+ eapply exec_straight_steps_1; eauto. lia. constructor.
econstructor; eauto.
change (rs5 PC) with (Val.offset_ptr (Val.offset_ptr (Val.offset_ptr (Val.offset_ptr (rs0 PC) Ptrofs.one) Ptrofs.one) Ptrofs.one) Ptrofs.one).
rewrite ATPC. simpl. constructor; eauto.
- eapply code_tail_next_int. omega.
- eapply code_tail_next_int. omega.
- eapply code_tail_next_int. omega.
- eapply code_tail_next_int. omega.
+ eapply code_tail_next_int. lia.
+ eapply code_tail_next_int. lia.
+ eapply code_tail_next_int. lia.
+ eapply code_tail_next_int. lia.
constructor.
unfold rs5, rs4, rs3, rs2.
apply agree_nextinstr. apply agree_nextinstr.
@@ -956,7 +969,7 @@ Local Transparent destroyed_by_jumptable.
- (* return *)
inv STACKS. simpl in *.
- right. split. omega. split. auto.
+ right. split. lia. split. auto.
rewrite <- ATPC in H5.
econstructor; eauto.
congruence.
diff --git a/powerpc/Asmgenproof1.v b/powerpc/Asmgenproof1.v
index 20cf9c1d..6ae520ef 100644
--- a/powerpc/Asmgenproof1.v
+++ b/powerpc/Asmgenproof1.v
@@ -81,12 +81,12 @@ Proof.
unfold Int.modu, Int.zero. decEq.
change 0 with (0 mod 65536).
change (Int.unsigned (Int.repr 65536)) with 65536.
- apply eqmod_mod_eq. omega.
+ apply eqmod_mod_eq. lia.
unfold x, low_s. eapply eqmod_trans.
apply eqmod_divides with Int.modulus.
unfold Int.sub. apply Int.eqm_unsigned_repr_l. apply Int.eqm_refl.
exists 65536. compute; auto.
- replace 0 with (Int.unsigned n - Int.unsigned n) by omega.
+ replace 0 with (Int.unsigned n - Int.unsigned n) by lia.
apply eqmod_sub. apply eqmod_refl. apply Int.eqmod_sign_ext'.
compute; auto.
rewrite H0 in H. rewrite Int.add_zero in H.
@@ -132,7 +132,7 @@ Lemma important_diff:
Proof.
congruence.
Qed.
-Hint Resolve important_diff: asmgen.
+Global Hint Resolve important_diff: asmgen.
Lemma important_data_preg_1:
forall r, data_preg r = true -> important_preg r = true.
@@ -146,7 +146,7 @@ Proof.
intros. destruct (data_preg r) eqn:E; auto. apply important_data_preg_1 in E. congruence.
Qed.
-Hint Resolve important_data_preg_1 important_data_preg_2: asmgen.
+Global Hint Resolve important_data_preg_1 important_data_preg_2: asmgen.
Lemma nextinstr_inv2:
forall r rs, important_preg r = true -> (nextinstr rs)#r = rs#r.
@@ -166,7 +166,7 @@ Lemma gpr_or_zero_zero:
Proof.
intros. reflexivity.
Qed.
-Hint Resolve gpr_or_zero_not_zero gpr_or_zero_zero: asmgen.
+Global Hint Resolve gpr_or_zero_not_zero gpr_or_zero_zero: asmgen.
Lemma gpr_or_zero_l_not_zero:
forall rs r, r <> GPR0 -> gpr_or_zero_l rs r = rs#r.
@@ -178,21 +178,21 @@ Lemma gpr_or_zero_l_zero:
Proof.
intros. reflexivity.
Qed.
-Hint Resolve gpr_or_zero_l_not_zero gpr_or_zero_l_zero: asmgen.
+Global Hint Resolve gpr_or_zero_l_not_zero gpr_or_zero_l_zero: asmgen.
Lemma ireg_of_not_GPR0:
forall m r, ireg_of m = OK r -> IR r <> IR GPR0.
Proof.
intros. erewrite <- ireg_of_eq; eauto with asmgen.
Qed.
-Hint Resolve ireg_of_not_GPR0: asmgen.
+Global Hint Resolve ireg_of_not_GPR0: asmgen.
Lemma ireg_of_not_GPR0':
forall m r, ireg_of m = OK r -> r <> GPR0.
Proof.
intros. generalize (ireg_of_not_GPR0 _ _ H). congruence.
Qed.
-Hint Resolve ireg_of_not_GPR0': asmgen.
+Global Hint Resolve ireg_of_not_GPR0': asmgen.
(** Useful properties of the LR register *)
@@ -208,7 +208,7 @@ Proof.
intros. rewrite preg_notin_charact. intros. apply preg_of_not_LR.
Qed.
-Hint Resolve preg_of_not_LR preg_notin_LR: asmgen.
+Global Hint Resolve preg_of_not_LR preg_notin_LR: asmgen.
(** Useful simplification tactic *)
@@ -543,7 +543,7 @@ Proof.
- econstructor; split; [|split].
+ apply exec_straight_one. simpl; eauto. auto.
+ Simpl. rewrite Int64.add_zero_l. rewrite H. unfold low64_s.
- rewrite Int64.sign_ext_widen by omega. auto.
+ rewrite Int64.sign_ext_widen by lia. auto.
+ intros; Simpl.
- econstructor; split; [|split].
+ eapply exec_straight_two. simpl; eauto. simpl; eauto. auto. auto.
@@ -551,16 +551,16 @@ Proof.
apply Int64.same_bits_eq; intros. assert (Int64.zwordsize = 64) by auto.
rewrite Int64.bits_or, Int64.bits_shl by auto.
unfold low64_s, low64_u.
- rewrite Int64.bits_zero_ext by omega.
+ rewrite Int64.bits_zero_ext by lia.
change (Int64.unsigned (Int64.repr 16)) with 16.
destruct (zlt i 16).
- * rewrite Int64.bits_sign_ext by omega. rewrite zlt_true by omega. auto.
- * rewrite ! Int64.bits_sign_ext by omega. rewrite orb_false_r.
+ * rewrite Int64.bits_sign_ext by lia. rewrite zlt_true by lia. auto.
+ * rewrite ! Int64.bits_sign_ext by lia. rewrite orb_false_r.
destruct (zlt i 32).
- ** rewrite zlt_true by omega. rewrite Int64.bits_shr by omega.
+ ** rewrite zlt_true by lia. rewrite Int64.bits_shr by lia.
change (Int64.unsigned (Int64.repr 16)) with 16.
- rewrite zlt_true by omega. f_equal; omega.
- ** rewrite zlt_false by omega. rewrite Int64.bits_shr by omega.
+ rewrite zlt_true by lia. f_equal; lia.
+ ** rewrite zlt_false by lia. rewrite Int64.bits_shr by lia.
change (Int64.unsigned (Int64.repr 16)) with 16.
reflexivity.
+ intros; Simpl.
@@ -605,11 +605,11 @@ Proof.
rewrite Int64.bits_shl by auto.
change (Int64.unsigned (Int64.repr 32)) with 32.
destruct (zlt i 32); auto.
- rewrite Int64.bits_sign_ext by omega.
- rewrite zlt_true by omega.
- unfold n2. rewrite Int64.bits_shru by omega.
+ rewrite Int64.bits_sign_ext by lia.
+ rewrite zlt_true by lia.
+ unfold n2. rewrite Int64.bits_shru by lia.
change (Int64.unsigned (Int64.repr 32)) with 32.
- rewrite zlt_true by omega. f_equal; omega.
+ rewrite zlt_true by lia. f_equal; lia.
}
assert (MI: forall i, 0 <= i < Int64.zwordsize ->
Int64.testbit mi i =
@@ -619,21 +619,21 @@ Proof.
rewrite Int64.bits_shl by auto.
change (Int64.unsigned (Int64.repr 16)) with 16.
destruct (zlt i 16); auto.
- unfold n1. rewrite Int64.bits_zero_ext by omega.
- rewrite Int64.bits_shru by omega.
+ unfold n1. rewrite Int64.bits_zero_ext by lia.
+ rewrite Int64.bits_shru by lia.
destruct (zlt i 32).
- rewrite zlt_true by omega.
+ rewrite zlt_true by lia.
change (Int64.unsigned (Int64.repr 16)) with 16.
- rewrite zlt_true by omega. f_equal; omega.
- rewrite zlt_false by omega. auto.
+ rewrite zlt_true by lia. f_equal; lia.
+ rewrite zlt_false by lia. auto.
}
assert (EQ: Int64.or (Int64.or hi mi) n0 = n).
{ apply Int64.same_bits_eq; intros.
rewrite ! Int64.bits_or by auto.
- unfold n0; rewrite Int64.bits_zero_ext by omega.
+ unfold n0; rewrite Int64.bits_zero_ext by lia.
rewrite HI, MI by auto.
destruct (zlt i 16).
- rewrite zlt_true by omega. auto.
+ rewrite zlt_true by lia. auto.
destruct (zlt i 32); rewrite ! orb_false_r; auto.
}
edestruct (loadimm64_32s_correct r n2) as (rs' & A & B & C).
@@ -805,6 +805,7 @@ Lemma accessind_load_correct:
forall (A: Type) (inj: A -> preg)
(instr1: A -> constant -> ireg -> instruction)
(instr2: A -> ireg -> ireg -> instruction)
+ (unaligned: bool)
(base: ireg) ofs rx chunk v (rs: regset) m k,
(forall rs m r1 cst r2,
exec_instr ge fn (instr1 r1 cst r2) rs m = load1 ge chunk (inj r1) cst r2 rs m) ->
@@ -813,14 +814,15 @@ Lemma accessind_load_correct:
Mem.loadv chunk m (Val.offset_ptr rs#base ofs) = Some v ->
base <> GPR0 -> inj rx <> PC ->
exists rs',
- exec_straight ge fn (accessind instr1 instr2 base ofs rx k) rs m k rs' m
+ exec_straight ge fn (accessind instr1 instr2 unaligned base ofs rx k) rs m k rs' m
/\ rs'#(inj rx) = v
/\ forall r, r <> PC -> r <> inj rx -> r <> GPR0 -> rs'#r = rs#r.
Proof.
intros. unfold accessind. set (ofs' := Ptrofs.to_int ofs) in *.
+ set (ofs_mod := unaligned || Int.eq (Int.mods ofs' (Int.repr 4)) Int.zero) in *.
assert (LD: Mem.loadv chunk m (Val.add (rs base) (Vint ofs')) = Some v)
by (apply loadv_offset_ptr; auto).
- destruct (Int.eq (high_s ofs') Int.zero).
+ destruct (Int.eq (high_s ofs') Int.zero && ofs_mod).
- econstructor; split. apply exec_straight_one.
rewrite H. unfold load1. rewrite gpr_or_zero_not_zero by auto. simpl.
rewrite LD. eauto. unfold nextinstr. repeat Simplif.
@@ -862,6 +864,7 @@ Lemma accessind_store_correct:
forall (A: Type) (inj: A -> preg)
(instr1: A -> constant -> ireg -> instruction)
(instr2: A -> ireg -> ireg -> instruction)
+ (unaligned: bool)
(base: ireg) ofs rx chunk (rs: regset) m m' k,
(forall rs m r1 cst r2,
exec_instr ge fn (instr1 r1 cst r2) rs m = store1 ge chunk (inj r1) cst r2 rs m) ->
@@ -870,13 +873,14 @@ Lemma accessind_store_correct:
Mem.storev chunk m (Val.offset_ptr rs#base ofs) (rs (inj rx)) = Some m' ->
base <> GPR0 -> inj rx <> PC -> inj rx <> GPR0 ->
exists rs',
- exec_straight ge fn (accessind instr1 instr2 base ofs rx k) rs m k rs' m'
+ exec_straight ge fn (accessind instr1 instr2 unaligned base ofs rx k) rs m k rs' m'
/\ forall r, r <> PC -> r <> GPR0 -> rs'#r = rs#r.
Proof.
intros. unfold accessind. set (ofs' := Ptrofs.to_int ofs) in *.
+ set (ofs_mod := unaligned || Int.eq (Int.mods ofs' (Int.repr 4)) Int.zero) in *.
assert (ST: Mem.storev chunk m (Val.add (rs base) (Vint ofs')) (rs (inj rx)) = Some m')
by (apply storev_offset_ptr; auto).
- destruct (Int.eq (high_s ofs') Int.zero).
+ destruct (Int.eq (high_s ofs') Int.zero && ofs_mod).
- econstructor; split. apply exec_straight_one.
rewrite H. unfold store1. rewrite gpr_or_zero_not_zero by auto. simpl.
rewrite ST. eauto. unfold nextinstr. repeat Simplif.
@@ -1180,7 +1184,7 @@ Local Transparent Int.repr.
rewrite H2. apply Int.mkint_eq; reflexivity.
rewrite Int.not_involutive in H3.
congruence.
- omega.
+ lia.
Qed.
Remark add_carry_ne0:
@@ -1198,8 +1202,8 @@ Transparent Int.eq.
rewrite Int.unsigned_zero. rewrite Int.unsigned_mone.
unfold negb, Val.of_bool, Vtrue, Vfalse.
destruct (zeq (Int.unsigned i) 0); decEq.
- apply zlt_true. omega.
- apply zlt_false. generalize (Int.unsigned_range i). omega.
+ apply zlt_true. lia.
+ apply zlt_false. generalize (Int.unsigned_range i). lia.
Qed.
Lemma transl_cond_op_correct:
@@ -1500,18 +1504,6 @@ Opaque Val.add.
- replace v with (Val.maketotal (Val.intoffloat (rs x))).
TranslOpSimpl.
rewrite H1; auto.
- (* Ointuoffloat *)
-- replace v with (Val.maketotal (Val.intuoffloat (rs x))).
- TranslOpSimpl.
- rewrite H1; auto.
- (* Ofloatofint *)
-- replace v with (Val.maketotal (Val.floatofint (rs x))).
- TranslOpSimpl.
- rewrite H1; auto.
- (* Ofloatofintu *)
-- replace v with (Val.maketotal (Val.floatofintu (rs x))).
- TranslOpSimpl.
- rewrite H1; auto.
(* Ocmp *)
- destruct (transl_cond_op_correct c0 args res k rs m c) as [rs' [A [B C]]]; auto.
exists rs'; auto with asmgen.
@@ -1552,8 +1544,8 @@ Qed.
(** Translation of memory accesses *)
Lemma transl_memory_access_correct:
- forall (P: regset -> Prop) mk1 mk2 addr args temp k c (rs: regset) a m m',
- transl_memory_access mk1 mk2 addr args temp k = OK c ->
+ forall (P: regset -> Prop) mk1 mk2 unaligned addr args temp k c (rs: regset) a m m',
+ transl_memory_access mk1 mk2 unaligned addr args temp k = OK c ->
eval_addressing ge (rs#GPR1) addr (map rs (map preg_of args)) = Some a ->
temp <> GPR0 ->
(forall cst (r1: ireg) (rs1: regset) k,
@@ -1571,111 +1563,178 @@ Lemma transl_memory_access_correct:
Proof.
intros until m'; intros TR ADDR TEMP MK1 MK2.
unfold transl_memory_access in TR; destruct addr; ArgsInv; simpl in ADDR; inv ADDR.
- (* Aindexed *)
- case (Int.eq (high_s i) Int.zero).
- (* Aindexed short *)
- apply MK1. rewrite gpr_or_zero_not_zero; eauto with asmgen. auto.
- (* Aindexed long *)
- set (rs1 := nextinstr (rs#temp <- (Val.add (rs x) (Vint (Int.shl (high_s i) (Int.repr 16)))))).
- exploit (MK1 (Cint (low_s i)) temp rs1 k).
- simpl. rewrite gpr_or_zero_not_zero; eauto with asmgen.
- unfold rs1; Simpl. rewrite Val.add_assoc.
-Transparent Val.add.
- simpl. rewrite low_high_s. auto.
- intros; unfold rs1; Simpl.
- intros [rs' [EX' AG']].
- exists rs'. split. apply exec_straight_step with rs1 m.
- simpl. rewrite gpr_or_zero_not_zero; eauto with asmgen. auto.
- auto. auto.
- (* Aindexed2 *)
- apply MK2. rewrite gpr_or_zero_not_zero; eauto with asmgen. auto.
- (* Aglobal *)
- destruct (symbol_is_small_data i i0) eqn:SISD; [ | destruct (symbol_is_rel_data i i0) ]; inv TR.
- (* Aglobal from small data *)
- apply MK1. unfold const_low. rewrite small_data_area_addressing by auto.
- rewrite add_zero_symbol_address. auto.
- auto.
- (* Aglobal from relative data *)
- set (rs1 := nextinstr (rs#temp <- (Val.add Vzero (high_half ge i i0)))).
- set (rs2 := nextinstr (rs1#temp <- (Genv.symbol_address ge i i0))).
- exploit (MK1 (Cint Int.zero) temp rs2).
- simpl. rewrite gpr_or_zero_not_zero by eauto with asmgen.
- unfold rs2. Simpl. rewrite Val.add_commut. rewrite add_zero_symbol_address. auto.
- intros; unfold rs2, rs1; Simpl.
- intros [rs' [EX' AG']].
- exists rs'; split. apply exec_straight_step with rs1 m; auto.
- apply exec_straight_step with rs2 m; auto. simpl. unfold rs2.
- rewrite gpr_or_zero_not_zero by eauto with asmgen. f_equal. f_equal. f_equal.
- unfold rs1; Simpl. apply low_high_half_zero.
- eexact EX'. auto.
- (* Aglobal from absolute data *)
- set (rs1 := nextinstr (rs#temp <- (Val.add Vzero (high_half ge i i0)))).
- exploit (MK1 (Csymbol_low i i0) temp rs1).
- simpl. rewrite gpr_or_zero_not_zero by eauto with asmgen.
- unfold rs1. Simpl. rewrite low_high_half_zero. auto.
- intros; unfold rs1; Simpl.
- intros [rs' [EX' AG']].
- exists rs'; split. apply exec_straight_step with rs1 m; auto.
- eexact EX'. auto.
- (* Abased *)
+ - (* Aindexed *)
+ unfold aindexed.
+ destruct (unaligned || Int.eq (Int.mods i (Int.repr 4)) Int.zero); [destruct (Int.eq (high_s i) Int.zero) |].
+ + (* Aindexed 4 aligned short *)
+ apply MK1. rewrite gpr_or_zero_not_zero; eauto with asmgen. auto.
+ (* Aindexed 4 aligned long *)
+ + set (rs1 := nextinstr (rs#temp <- (Val.add (rs x) (Vint (Int.shl (high_s i) (Int.repr 16)))))).
+ exploit (MK1 (Cint (low_s i)) temp rs1 k).
+ simpl. rewrite gpr_or_zero_not_zero; eauto with asmgen.
+ unfold rs1; Simpl. rewrite Val.add_assoc.
+ Transparent Val.add.
+ simpl. rewrite low_high_s. auto.
+ intros; unfold rs1; Simpl.
+ intros [rs' [EX' AG']].
+ exists rs'. split. apply exec_straight_step with rs1 m.
+ simpl. rewrite gpr_or_zero_not_zero; eauto with asmgen. auto.
+ auto. auto.
+ + (* Aindexed non 4 aligned *)
+ exploit (loadimm_correct GPR0 i (mk2 x GPR0 :: k) rs).
+ intros (rs' & A & B & C).
+ exploit (MK2 x GPR0 rs').
+ rewrite gpr_or_zero_not_zero; eauto with asmgen.
+ rewrite B. rewrite C; eauto with asmgen. auto.
+ intros. destruct H as [rs'' [A1 B1]]. exists rs''.
+ split. eapply exec_straight_trans. exact A. exact A1. auto.
+ - (* Aindexed2 *)
+ apply MK2. rewrite gpr_or_zero_not_zero; eauto with asmgen. auto.
+ - (* Aglobal *)
+ unfold aglobal in *.
+ destruct (symbol_is_small_data i i0) eqn:SISD; [ | destruct (symbol_is_rel_data i i0) ]; inv TR.
+ + (* Aglobal from small data 4 aligned *)
+ case (unaligned || symbol_ofs_word_aligned i i0).
+ apply MK1. unfold const_low. rewrite small_data_area_addressing by auto.
+ rewrite add_zero_symbol_address. auto. auto.
+ (* Aglobal from small data not aligned *)
+ set (rs1 := nextinstr (rs#temp <- (Val.add (gpr_or_zero rs GPR0) (const_low ge (Csymbol_sda i i0))))).
+ exploit (MK1 (Cint Int.zero) temp rs1). rewrite gpr_or_zero_not_zero; auto.
+ unfold const_low. unfold rs1. Simpl.
+ rewrite gpr_or_zero_zero. unfold const_low.
+ rewrite small_data_area_addressing by auto.
+ rewrite add_zero_symbol_address. rewrite Val.add_commut.
+ rewrite add_zero_symbol_address. auto.
+ intros. unfold rs1. Simpl.
+ intros. destruct H as [rs2 [A B]].
+ exists rs2. split. eapply exec_straight_step. reflexivity.
+ reflexivity. eexact A. apply B.
+ + (* relative data *)
+ set (rs1 := nextinstr (rs#temp <- (Val.add Vzero (high_half ge i i0)))).
+ set (rs2 := nextinstr (rs1#temp <- (Genv.symbol_address ge i i0))).
+ exploit (MK1 (Cint Int.zero) temp rs2).
+ simpl. rewrite gpr_or_zero_not_zero by eauto with asmgen.
+ unfold rs2. Simpl. rewrite Val.add_commut. rewrite add_zero_symbol_address. auto.
+ intros; unfold rs2, rs1; Simpl.
+ intros [rs' [EX' AG']].
+ exists rs'; split. apply exec_straight_step with rs1 m; auto.
+ apply exec_straight_step with rs2 m; auto. simpl. unfold rs2.
+ rewrite gpr_or_zero_not_zero by eauto with asmgen. f_equal. f_equal. f_equal.
+ unfold rs1; Simpl. apply low_high_half_zero.
+ eexact EX'. auto.
+ + (* Aglobal from absolute data *)
+ destruct (unaligned || symbol_ofs_word_aligned i i0).
+ (* Aglobal 4 aligned *)
+ set (rs1 := nextinstr (rs#temp <- (Val.add Vzero (high_half ge i i0)))).
+ exploit (MK1 (Csymbol_low i i0) temp rs1).
+ simpl. rewrite gpr_or_zero_not_zero by eauto with asmgen.
+ unfold rs1. Simpl. rewrite low_high_half_zero. auto.
+ intros; unfold rs1; Simpl.
+ intros [rs' [EX' AG']].
+ exists rs'; split. apply exec_straight_step with rs1 m; auto.
+ eexact EX'. auto.
+ (* Aglobal non aligned *)
+ set (rs1 := nextinstr (rs#temp <- (Val.add Vzero (high_half ge i i0)))).
+ set (rs2 := nextinstr (rs1#temp <- (Genv.symbol_address ge i i0))).
+ exploit (MK1 (Cint Int.zero) temp rs2).
+ simpl. rewrite gpr_or_zero_not_zero by eauto with asmgen.
+ unfold rs2. Simpl. rewrite Val.add_commut. rewrite add_zero_symbol_address.
+ auto. intros; unfold rs2, rs1; Simpl.
+ intros [rs' [EX' AG']].
+ exists rs'; split. apply exec_straight_step with rs1 m; auto.
+ apply exec_straight_step with rs2 m; auto. simpl. unfold rs2.
+ rewrite gpr_or_zero_not_zero; auto. f_equal. f_equal. f_equal.
+ unfold rs1; Simpl. apply low_high_half_zero. eexact EX'. auto.
+ - (* Abased *)
+ unfold abased in *.
destruct (symbol_is_small_data i i0) eqn:SISD; [ | destruct (symbol_is_rel_data i i0) ].
- (* Abased from small data *)
- set (rs1 := nextinstr (rs#GPR0 <- (Genv.symbol_address ge i i0))).
- exploit (MK2 x GPR0 rs1 k).
+ + (* Abased from small data *)
+ set (rs1 := nextinstr (rs#GPR0 <- (Genv.symbol_address ge i i0))).
+ exploit (MK2 x GPR0 rs1 k).
simpl. rewrite gpr_or_zero_not_zero by eauto with asmgen.
unfold rs1; Simpl. rewrite Val.add_commut. auto.
intros. unfold rs1; Simpl.
- intros [rs' [EX' AG']].
- exists rs'; split. apply exec_straight_step with rs1 m.
- unfold exec_instr. rewrite gpr_or_zero_zero. f_equal. unfold rs1. f_equal. f_equal.
- unfold const_low. rewrite small_data_area_addressing; auto.
- apply add_zero_symbol_address.
- reflexivity.
- assumption. assumption.
- (* Abased from relative data *)
- set (rs1 := nextinstr (rs#GPR0 <- (rs#x))).
- set (rs2 := nextinstr (rs1#temp <- (Val.add Vzero (high_half ge i i0)))).
- set (rs3 := nextinstr (rs2#temp <- (Genv.symbol_address ge i i0))).
- exploit (MK2 temp GPR0 rs3).
+ intros [rs' [EX' AG']].
+ exists rs'; split. apply exec_straight_step with rs1 m.
+ unfold exec_instr. rewrite gpr_or_zero_zero. f_equal. unfold rs1. f_equal. f_equal.
+ unfold const_low. rewrite small_data_area_addressing; auto.
+ apply add_zero_symbol_address.
+ reflexivity.
+ assumption. assumption.
+ + (* Abased from relative data *)
+ set (rs1 := nextinstr (rs#GPR0 <- (rs#x))).
+ set (rs2 := nextinstr (rs1#temp <- (Val.add Vzero (high_half ge i i0)))).
+ set (rs3 := nextinstr (rs2#temp <- (Genv.symbol_address ge i i0))).
+ exploit (MK2 temp GPR0 rs3).
rewrite gpr_or_zero_not_zero by eauto with asmgen.
f_equal. unfold rs3; Simpl. unfold rs3, rs2, rs1; Simpl.
intros. unfold rs3, rs2, rs1; Simpl.
- intros [rs' [EX' AG']].
- exists rs'. split. eapply exec_straight_trans with (rs2 := rs3) (m2 := m).
- apply exec_straight_three with rs1 m rs2 m; auto.
- simpl. unfold rs3. f_equal. f_equal. f_equal. rewrite gpr_or_zero_not_zero by auto.
- unfold rs2; Simpl. apply low_high_half_zero.
- eexact EX'. auto.
- (* Abased absolute *)
- set (rs1 := nextinstr (rs#temp <- (Val.add (rs x) (high_half ge i i0)))).
- exploit (MK1 (Csymbol_low i i0) temp rs1 k).
+ intros [rs' [EX' AG']].
+ exists rs'. split. eapply exec_straight_trans with (rs2 := rs3) (m2 := m).
+ apply exec_straight_three with rs1 m rs2 m; auto.
+ simpl. unfold rs3. f_equal. f_equal. f_equal. rewrite gpr_or_zero_not_zero by auto.
+ unfold rs2; Simpl. apply low_high_half_zero.
+ eexact EX'. auto.
+ + (* Abased absolute *)
+ destruct (unaligned || symbol_ofs_word_aligned i i0).
+ (* Abased absolute 4 aligned *)
+ set (rs1 := nextinstr (rs#temp <- (Val.add (rs x) (high_half ge i i0)))).
+ exploit (MK1 (Csymbol_low i i0) temp rs1 k).
simpl. rewrite gpr_or_zero_not_zero; eauto with asmgen.
unfold rs1. Simpl.
rewrite Val.add_assoc. rewrite low_high_half. rewrite Val.add_commut. auto.
intros; unfold rs1; Simpl.
- intros [rs' [EX' AG']].
- exists rs'. split. apply exec_straight_step with rs1 m.
- unfold exec_instr. rewrite gpr_or_zero_not_zero; eauto with asmgen. auto.
- assumption. assumption.
- (* Ainstack *)
- set (ofs := Ptrofs.to_int i) in *.
- assert (L: Val.lessdef (Val.offset_ptr (rs GPR1) i) (Val.add (rs GPR1) (Vint ofs))).
- { destruct (rs GPR1); simpl; auto. unfold ofs; rewrite Ptrofs.of_int_to_int; auto. }
- destruct (Int.eq (high_s ofs) Int.zero); inv TR.
- apply MK1. simpl. rewrite gpr_or_zero_not_zero; eauto with asmgen. auto.
- set (rs1 := nextinstr (rs#temp <- (Val.add rs#GPR1 (Vint (Int.shl (high_s ofs) (Int.repr 16)))))).
- exploit (MK1 (Cint (low_s ofs)) temp rs1 k).
- simpl. rewrite gpr_or_zero_not_zero; auto.
- unfold rs1. rewrite nextinstr_inv. rewrite Pregmap.gss.
- rewrite Val.add_assoc. simpl. rewrite low_high_s. auto.
- congruence.
- intros. unfold rs1. rewrite nextinstr_inv; auto. apply Pregmap.gso; auto.
- intros [rs' [EX' AG']].
- exists rs'. split. apply exec_straight_step with rs1 m.
- unfold exec_instr. rewrite gpr_or_zero_not_zero; eauto with asmgen. auto.
- assumption. assumption.
+ intros [rs' [EX' AG']].
+ exists rs'. split. apply exec_straight_step with rs1 m.
+ unfold exec_instr. rewrite gpr_or_zero_not_zero; eauto with asmgen. auto.
+ assumption. assumption.
+ (* Abased absolute non aligned *)
+ set (rs1 := nextinstr (rs#GPR0 <- (rs#x))).
+ set (rs2 := nextinstr (rs1#temp <- (Val.add Vzero (high_half ge i i0)))).
+ set (rs3 := nextinstr (rs2#temp <- (Genv.symbol_address ge i i0))).
+ exploit (MK2 temp GPR0 rs3).
+ rewrite gpr_or_zero_not_zero by eauto with asmgen.
+ f_equal. unfold rs3; Simpl. unfold rs3, rs2, rs1; Simpl.
+ intros. unfold rs3, rs2, rs1; Simpl.
+ intros [rs' [EX' AG']].
+ exists rs'. split. eapply exec_straight_trans with (rs2 := rs3) (m2 := m).
+ apply exec_straight_three with rs1 m rs2 m; auto.
+ simpl. unfold rs3. f_equal. f_equal. f_equal. rewrite gpr_or_zero_not_zero by auto.
+ unfold rs2; Simpl. apply low_high_half_zero.
+ eexact EX'. auto.
+ - (* Ainstack *)
+ unfold ainstack in *.
+ set (ofs := Ptrofs.to_int i) in *.
+ assert (L: Val.lessdef (Val.offset_ptr (rs GPR1) i) (Val.add (rs GPR1) (Vint ofs))).
+ { destruct (rs GPR1); simpl; auto. unfold ofs; rewrite Ptrofs.of_int_to_int; auto. }
+ destruct (unaligned || Int.eq (Int.mods ofs (Int.repr 4)) Int.zero); [destruct (Int.eq (high_s ofs) Int.zero)|]; inv TR.
+ + (* Ainstack short *)
+ apply MK1. simpl. rewrite gpr_or_zero_not_zero; eauto with asmgen. auto.
+ + (* Ainstack non short *)
+ set (rs1 := nextinstr (rs#temp <- (Val.add rs#GPR1 (Vint (Int.shl (high_s ofs) (Int.repr 16)))))).
+ exploit (MK1 (Cint (low_s ofs)) temp rs1 k).
+ simpl. rewrite gpr_or_zero_not_zero; auto.
+ unfold rs1. rewrite nextinstr_inv. rewrite Pregmap.gss.
+ rewrite Val.add_assoc. simpl. rewrite low_high_s. auto.
+ congruence.
+ intros. unfold rs1. rewrite nextinstr_inv; auto. apply Pregmap.gso; auto.
+ intros [rs' [EX' AG']].
+ exists rs'. split. apply exec_straight_step with rs1 m.
+ unfold exec_instr. rewrite gpr_or_zero_not_zero; eauto with asmgen. auto.
+ assumption. assumption.
+ + (* Ainstack non aligned *)
+ exploit (addimm_correct temp GPR1 ofs (mk1 (Cint Int.zero) temp :: k) rs); eauto with asmgen.
+ intros [rs1 [A [B C]]].
+ exploit (MK1 (Cint Int.zero) temp rs1 k).
+ rewrite gpr_or_zero_not_zero; auto. rewrite B. simpl.
+ destruct (rs GPR1); auto. simpl. rewrite Ptrofs.add_zero.
+ unfold ofs. rewrite Ptrofs.of_int_to_int. auto. auto.
+ intros. rewrite C; auto. intros [rs2 [EX' AG']].
+ exists rs2. split; auto.
+ eapply exec_straight_trans. eexact A. assumption.
Qed.
+
(** Translation of loads *)
Lemma transl_load_correct:
@@ -1691,8 +1750,8 @@ Proof.
intros.
assert (LD: forall v, Val.lessdef a v -> v = a).
{ intros. inv H2; auto. discriminate H1. }
- assert (BASE: forall mk1 mk2 k' chunk' v',
- transl_memory_access mk1 mk2 addr args GPR12 k' = OK c ->
+ assert (BASE: forall mk1 mk2 unaligned k' chunk' v',
+ transl_memory_access mk1 mk2 unaligned addr args GPR12 k' = OK c ->
Mem.loadv chunk' m a = Some v' ->
(forall cst (r1: ireg) (rs1: regset),
exec_instr ge fn (mk1 cst r1) rs1 m =
@@ -1770,8 +1829,8 @@ Local Transparent destroyed_by_store.
subst src; simpl; congruence.
change (IR GPR12) with (preg_of R12). red; intros; elim n.
eapply preg_of_injective; eauto.
- assert (BASE: forall mk1 mk2 chunk',
- transl_memory_access mk1 mk2 addr args (int_temp_for src) k = OK c ->
+ assert (BASE: forall mk1 mk2 unaligned chunk',
+ transl_memory_access mk1 mk2 unaligned addr args (int_temp_for src) k = OK c ->
Mem.storev chunk' m a (rs (preg_of src)) = Some m' ->
(forall cst (r1: ireg) (rs1: regset),
exec_instr ge fn (mk1 cst r1) rs1 m =
diff --git a/powerpc/Builtins1.v b/powerpc/Builtins1.v
index 9d7aadd9..b3fdebd0 100644
--- a/powerpc/Builtins1.v
+++ b/powerpc/Builtins1.v
@@ -6,10 +6,11 @@
(* *)
(* Copyright Institut National de Recherche en Informatique et en *)
(* Automatique. All rights reserved. This file is distributed *)
-(* under the terms of the GNU General Public License as published by *)
-(* the Free Software Foundation, either version 2 of the License, or *)
-(* (at your option) any later version. This file is also distributed *)
-(* under the terms of the INRIA Non-Commercial License Agreement. *)
+(* under the terms of the GNU Lesser General Public License as *)
+(* published by the Free Software Foundation, either version 2.1 of *)
+(* the License, or (at your option) any later version. *)
+(* This file is also distributed under the terms of the *)
+(* INRIA Non-Commercial License Agreement. *)
(* *)
(* *********************************************************************)
diff --git a/powerpc/CBuiltins.ml b/powerpc/CBuiltins.ml
index e0826877..dc8aa73a 100644
--- a/powerpc/CBuiltins.ml
+++ b/powerpc/CBuiltins.ml
@@ -6,10 +6,11 @@
(* *)
(* Copyright Institut National de Recherche en Informatique et en *)
(* Automatique. All rights reserved. This file is distributed *)
-(* under the terms of the GNU General Public License as published by *)
-(* the Free Software Foundation, either version 2 of the License, or *)
-(* (at your option) any later version. This file is also distributed *)
-(* under the terms of the INRIA Non-Commercial License Agreement. *)
+(* under the terms of the GNU Lesser General Public License as *)
+(* published by the Free Software Foundation, either version 2.1 of *)
+(* the License, or (at your option) any later version. *)
+(* This file is also distributed under the terms of the *)
+(* INRIA Non-Commercial License Agreement. *)
(* *)
(* *********************************************************************)
diff --git a/powerpc/ConstpropOpproof.v b/powerpc/ConstpropOpproof.v
index 8687b056..1dd2e0e4 100644
--- a/powerpc/ConstpropOpproof.v
+++ b/powerpc/ConstpropOpproof.v
@@ -374,7 +374,7 @@ Proof.
Int.bit_solve. destruct (zlt i0 n0).
replace (Int.testbit n i0) with (negb (Int.testbit Int.zero i0)).
rewrite Int.bits_zero. simpl. rewrite andb_true_r. auto.
- rewrite <- EQ. rewrite Int.bits_zero_ext by omega. rewrite zlt_true by auto.
+ rewrite <- EQ. rewrite Int.bits_zero_ext by lia. rewrite zlt_true by auto.
rewrite Int.bits_not by auto. apply negb_involutive.
rewrite H6 by auto. auto.
econstructor; split; eauto. auto.
diff --git a/powerpc/Conventions1.v b/powerpc/Conventions1.v
index 5c9cbd4f..f05e77df 100644
--- a/powerpc/Conventions1.v
+++ b/powerpc/Conventions1.v
@@ -268,7 +268,7 @@ Remark loc_arguments_rec_charact:
forall_rpair (loc_argument_charact ofs) p.
Proof.
assert (X: forall ofs1 ofs2 l, loc_argument_charact ofs2 l -> ofs1 <= ofs2 -> loc_argument_charact ofs1 l).
- { destruct l; simpl; intros; auto. destruct sl; auto. intuition omega. }
+ { destruct l; simpl; intros; auto. destruct sl; auto. intuition lia. }
assert (Y: forall ofs1 ofs2 p, forall_rpair (loc_argument_charact ofs2) p -> ofs1 <= ofs2 -> forall_rpair (loc_argument_charact ofs1) p).
{ destruct p; simpl; intuition eauto. }
Opaque list_nth_z.
@@ -279,52 +279,52 @@ Opaque list_nth_z.
destruct (list_nth_z int_param_regs ir) as [r|] eqn:E; destruct H.
subst. left. eapply list_nth_z_in; eauto.
eapply IHtyl; eauto.
- subst. split. omega. apply Z.divide_1_l.
- eapply Y; eauto. omega.
+ subst. split. lia. apply Z.divide_1_l.
+ eapply Y; eauto. lia.
- (* float *)
- assert (ofs <= align ofs 2) by (apply align_le; omega).
+ assert (ofs <= align ofs 2) by (apply align_le; lia).
destruct (list_nth_z float_param_regs fr) as [r|] eqn:E; destruct H.
subst. right. eapply list_nth_z_in; eauto.
eapply IHtyl; eauto.
- subst. split. omega. apply Z.divide_1_l.
- eapply Y; eauto. omega.
+ subst. split. lia. apply Z.divide_1_l.
+ eapply Y; eauto. lia.
- (* long *)
- assert (ofs <= align ofs 2) by (apply align_le; omega).
+ assert (ofs <= align ofs 2) by (apply align_le; lia).
set (ir' := align ir 2) in *.
destruct (list_nth_z int_param_regs ir') as [r1|] eqn:E1.
destruct (list_nth_z int_param_regs (ir' + 1)) as [r2|] eqn:E2.
destruct H. subst; split; left; eapply list_nth_z_in; eauto.
eapply IHtyl; eauto.
destruct H.
- subst. destruct Archi.ptr64; [split|split;split]; try omega.
- apply align_divides; omega. apply Z.divide_1_l. apply Z.divide_1_l.
- eapply Y; eauto. omega.
+ subst. destruct Archi.ptr64; [split|split;split]; try lia.
+ apply align_divides; lia. apply Z.divide_1_l. apply Z.divide_1_l.
+ eapply Y; eauto. lia.
destruct H.
- subst. destruct Archi.ptr64; [split|split;split]; try omega.
- apply align_divides; omega. apply Z.divide_1_l. apply Z.divide_1_l.
- eapply Y; eauto. omega.
+ subst. destruct Archi.ptr64; [split|split;split]; try lia.
+ apply align_divides; lia. apply Z.divide_1_l. apply Z.divide_1_l.
+ eapply Y; eauto. lia.
- (* single *)
- assert (ofs <= align ofs 1) by (apply align_le; omega).
- assert (ofs <= align ofs 2) by (apply align_le; omega).
+ assert (ofs <= align ofs 1) by (apply align_le; lia).
+ assert (ofs <= align ofs 2) by (apply align_le; lia).
destruct (list_nth_z float_param_regs fr) as [r|] eqn:E; destruct H.
subst. right. eapply list_nth_z_in; eauto.
eapply IHtyl; eauto.
- subst. split. destruct Archi.single_passed_as_single; simpl; omega.
+ subst. split. destruct Archi.single_passed_as_single; simpl; lia.
destruct Archi.single_passed_as_single; simpl; apply Z.divide_1_l.
- eapply Y; eauto. destruct Archi.single_passed_as_single; simpl; omega.
+ eapply Y; eauto. destruct Archi.single_passed_as_single; simpl; lia.
- (* any32 *)
destruct (list_nth_z int_param_regs ir) as [r|] eqn:E; destruct H.
subst. left. eapply list_nth_z_in; eauto.
eapply IHtyl; eauto.
- subst. split. omega. apply Z.divide_1_l.
- eapply Y; eauto. omega.
+ subst. split. lia. apply Z.divide_1_l.
+ eapply Y; eauto. lia.
- (* float *)
- assert (ofs <= align ofs 2) by (apply align_le; omega).
+ assert (ofs <= align ofs 2) by (apply align_le; lia).
destruct (list_nth_z float_param_regs fr) as [r|] eqn:E; destruct H.
subst. right. eapply list_nth_z_in; eauto.
eapply IHtyl; eauto.
- subst. split. omega. apply Z.divide_1_l.
- eapply Y; eauto. omega.
+ subst. split. lia. apply Z.divide_1_l.
+ eapply Y; eauto. lia.
Qed.
Lemma loc_arguments_acceptable:
@@ -341,7 +341,7 @@ Proof.
unfold forall_rpair; destruct p; intuition auto.
Qed.
-Hint Resolve loc_arguments_acceptable: locs.
+Global Hint Resolve loc_arguments_acceptable: locs.
Lemma loc_arguments_main:
loc_arguments signature_main = nil.
@@ -349,8 +349,9 @@ Proof.
reflexivity.
Qed.
-(** ** Normalization of function results *)
+(** ** Normalization of function results and parameters *)
(** No normalization needed. *)
Definition return_value_needs_normalization (t: rettype) := false.
+Definition parameter_needs_normalization (t: rettype) := false.
diff --git a/powerpc/Machregs.v b/powerpc/Machregs.v
index 07622a0e..9967bbae 100644
--- a/powerpc/Machregs.v
+++ b/powerpc/Machregs.v
@@ -166,7 +166,7 @@ Definition destroyed_by_op (op: operation): list mreg :=
| Ofloatconst _ => R12 :: nil
| Osingleconst _ => R12 :: nil
| Olongconst _ => R12 :: nil
- | Ointoffloat | Ointuoffloat => F13 :: nil
+ | Ointoffloat => F13 :: nil
| Olongoffloat => F13 :: nil
| Oaddlimm _ => R12 :: nil
| Oandlimm _ => R12 :: nil
diff --git a/powerpc/NeedOp.v b/powerpc/NeedOp.v
index 5ea09bd8..85dd9b2e 100644
--- a/powerpc/NeedOp.v
+++ b/powerpc/NeedOp.v
@@ -61,7 +61,7 @@ Definition needs_of_operation (op: operation) (nv: nval): list nval :=
| Onegfs | Oabsfs => op1 (default nv)
| Oaddfs | Osubfs | Omulfs | Odivfs => op2 (default nv)
| Osingleoffloat | Ofloatofsingle => op1 (default nv)
- | Ointoffloat | Ointuoffloat | Ofloatofint | Ofloatofintu => op1 (default nv)
+ | Ointoffloat => op1 (default nv)
| Ofloatofwords | Omakelong => op2 (default nv)
| Olowlong | Ohighlong => op1 (default nv)
| Ocmp c => needs_of_condition c
@@ -162,8 +162,8 @@ Lemma operation_is_redundant_sound:
vagree v arg1' nv.
Proof.
intros. destruct op; simpl in *; try discriminate; inv H1; FuncInv; subst.
-- apply sign_ext_redundant_sound; auto. omega.
-- apply sign_ext_redundant_sound; auto. omega.
+- apply sign_ext_redundant_sound; auto. lia.
+- apply sign_ext_redundant_sound; auto. lia.
- apply andimm_redundant_sound; auto.
- apply orimm_redundant_sound; auto.
- apply rolm_redundant_sound; auto.
diff --git a/powerpc/Op.v b/powerpc/Op.v
index 0f082c1f..a96a0439 100644
--- a/powerpc/Op.v
+++ b/powerpc/Op.v
@@ -105,7 +105,7 @@ Inductive operation : Type :=
| Osubl: operation (**r [rd = r1 - r2] *)
| Onegl: operation (**r [rd = - r1] *)
| Omull: operation (**r [rd = r1 * r2] *)
- | Omullhs: operation (**r [rd = high part of r1 * r2, signed] *)
+ | Omullhs: operation (**r [rd = high part of r1 * r2, signed] *)
| Omullhu: operation (**r [rd = high part of r1 * r2, unsigned] *)
| Odivl: operation (**r [rd = r1 / r2] (signed) *)
| Odivlu: operation (**r [rd = r1 / r2] (unsigned) *)
@@ -141,9 +141,6 @@ Inductive operation : Type :=
| Ofloatofsingle: operation (**r [rd] is [r1] extended to double-precision float *)
(*c Conversions between int and float: *)
| Ointoffloat: operation (**r [rd = signed_int_of_float(r1)] *)
- | Ointuoffloat: operation (**r [rd = unsigned_int_of_float(r1)] (PPC64 only) *)
- | Ofloatofint: operation (**r [rd = float_of_signed_int(r1)] (PPC64 only) *)
- | Ofloatofintu: operation (**r [rd = float_of_unsigned_int(r1)] (PPC64 only *)
| Ofloatofwords: operation (**r [rd = float_of_words(r1,r2)] *)
(*c Manipulating 64-bit integers: *)
| Omakelong: operation (**r [rd = r1 << 32 | r2] *)
@@ -299,9 +296,6 @@ Definition eval_operation
| Osingleoffloat, v1::nil => Some(Val.singleoffloat v1)
| Ofloatofsingle, v1::nil => Some(Val.floatofsingle v1)
| Ointoffloat, v1::nil => Val.intoffloat v1
- | Ointuoffloat, v1::nil => Val.intuoffloat v1
- | Ofloatofint, v1::nil => Val.floatofint v1
- | Ofloatofintu, v1::nil => Val.floatofintu v1
| Ofloatofwords, v1::v2::nil => Some(Val.floatofwords v1 v2)
| Omakelong, v1::v2::nil => Some(Val.longofwords v1 v2)
| Olowlong, v1::nil => Some(Val.loword v1)
@@ -449,9 +443,6 @@ Definition type_of_operation (op: operation) : list typ * typ :=
| Osingleoffloat => (Tfloat :: nil, Tsingle)
| Ofloatofsingle => (Tsingle :: nil, Tfloat)
| Ointoffloat => (Tfloat :: nil, Tint)
- | Ointuoffloat => (Tfloat :: nil, Tint)
- | Ofloatofint => (Tint :: nil, Tfloat)
- | Ofloatofintu => (Tint :: nil, Tfloat)
| Ofloatofwords => (Tint :: Tint :: nil, Tfloat)
| Omakelong => (Tint :: Tint :: nil, Tlong)
| Olowlong => (Tlong :: nil, Tint)
@@ -570,9 +561,6 @@ Proof with (try exact I; try reflexivity).
destruct v0...
destruct v0...
destruct v0; simpl in H0; inv H0. destruct (Float.to_int f); inv H2...
- destruct v0; simpl in H0; inv H0. destruct (Float.to_intu f); inv H2...
- destruct v0; simpl in H0; inv H0...
- destruct v0; simpl in H0; inv H0...
destruct v0; destruct v1...
destruct v0; destruct v1...
destruct v0...
@@ -999,10 +987,6 @@ Proof.
inv H4; simpl; auto.
inv H4; simpl in H1; inv H1. simpl. destruct (Float.to_int f0); simpl in H2; inv H2.
exists (Vint i); auto.
- inv H4; simpl in H1; inv H1. simpl. destruct (Float.to_intu f0); simpl in H2; inv H2.
- exists (Vint i); auto.
- inv H4; simpl in H1; inv H1; simpl. TrivialExists.
- inv H4; simpl in H1; inv H1; simpl. TrivialExists.
inv H4; inv H2; simpl; auto.
inv H4; inv H2; simpl; auto.
inv H4; simpl; auto.
diff --git a/powerpc/SelectLongproof.v b/powerpc/SelectLongproof.v
index f16c967e..ea14668f 100644
--- a/powerpc/SelectLongproof.v
+++ b/powerpc/SelectLongproof.v
@@ -221,15 +221,15 @@ Proof.
change (Int64.unsigned Int64.iwordsize) with 64.
f_equal.
rewrite Int.unsigned_repr.
- apply eqmod_mod_eq. omega.
+ apply eqmod_mod_eq. lia.
apply eqmod_trans with a.
apply eqmod_divides with Int.modulus. apply Int.eqm_sym. apply Int.eqm_unsigned_repr.
exists (two_p (32-6)); auto.
apply eqmod_divides with Int64.modulus. apply Int64.eqm_unsigned_repr.
exists (two_p (64-6)); auto.
- assert (0 <= Int.unsigned (Int.repr a) mod 64 < 64) by (apply Z_mod_lt; omega).
+ assert (0 <= Int.unsigned (Int.repr a) mod 64 < 64) by (apply Z_mod_lt; lia).
assert (64 < Int.max_unsigned) by (compute; auto).
- omega.
+ lia.
- InvEval. TrivialExists. simpl. rewrite <- H.
unfold Val.rolml; destruct v1; simpl; auto. unfold Int64.rolm.
rewrite Int64.rol_and. rewrite Int64.and_assoc. auto.
diff --git a/powerpc/SelectOp.vp b/powerpc/SelectOp.vp
index ba6612e8..cd9a65df 100644
--- a/powerpc/SelectOp.vp
+++ b/powerpc/SelectOp.vp
@@ -468,7 +468,7 @@ Definition intoffloat (e: expr) := Eop Ointoffloat (e ::: Enil).
Definition intuoffloat (e: expr) :=
if Archi.ppc64 then
- Eop Ointuoffloat (e ::: Enil)
+ Eop Olowlong (Eop Olongoffloat (e ::: Enil) ::: Enil)
else
Elet e
(Elet (Eop (Ofloatconst (Float.of_intu Float.ox8000_0000)) Enil)
@@ -482,7 +482,8 @@ Nondetfunction floatofintu (e: expr) :=
Eop (Ofloatconst (Float.of_intu n)) Enil
| _ =>
if Archi.ppc64 then
- Eop Ofloatofintu (e ::: Enil) else
+ Eop Ofloatoflong (Eop Ocast32unsigned (e ::: Enil) ::: Enil)
+ else
subf (Eop Ofloatofwords (Eop (Ointconst Float.ox4330_0000) Enil ::: e ::: Enil))
(Eop (Ofloatconst (Float.from_words Float.ox4330_0000 Int.zero)) Enil)
end.
@@ -493,7 +494,8 @@ Nondetfunction floatofint (e: expr) :=
Eop (Ofloatconst (Float.of_int n)) Enil
| _ =>
if Archi.ppc64 then
- Eop Ofloatofint (e ::: Enil) else
+ Eop Ofloatoflong (Eop Ocast32signed (e ::: Enil) ::: Enil)
+ else
subf (Eop Ofloatofwords (Eop (Ointconst Float.ox4330_0000) Enil
::: addimm Float.ox8000_0000 e ::: Enil))
(Eop (Ofloatconst (Float.from_words Float.ox4330_0000 Float.ox8000_0000)) Enil)
diff --git a/powerpc/SelectOpproof.v b/powerpc/SelectOpproof.v
index c3eda068..adac6c34 100644
--- a/powerpc/SelectOpproof.v
+++ b/powerpc/SelectOpproof.v
@@ -805,7 +805,7 @@ Qed.
Theorem eval_cast8unsigned: unary_constructor_sound cast8unsigned (Val.zero_ext 8).
Proof.
red; intros. unfold cast8unsigned.
- rewrite Val.zero_ext_and. apply eval_andimm; auto. omega.
+ rewrite Val.zero_ext_and. apply eval_andimm; auto. lia.
Qed.
Theorem eval_cast16signed: unary_constructor_sound cast16signed (Val.sign_ext 16).
@@ -818,7 +818,7 @@ Qed.
Theorem eval_cast16unsigned: unary_constructor_sound cast16unsigned (Val.zero_ext 16).
Proof.
red; intros. unfold cast16unsigned.
- rewrite Val.zero_ext_and. apply eval_andimm; auto. omega.
+ rewrite Val.zero_ext_and. apply eval_andimm; auto. lia.
Qed.
Theorem eval_singleoffloat: unary_constructor_sound singleoffloat Val.singleoffloat.
@@ -851,8 +851,13 @@ Proof.
destruct (Float.to_intu f) as [n|] eqn:?; simpl in H0; inv H0.
exists (Vint n); split; auto. unfold intuoffloat.
destruct Archi.ppc64.
- econstructor. constructor; eauto. constructor. simpl; rewrite Heqo; auto.
- set (im := Int.repr Int.half_modulus).
+- apply Float.to_intu_to_long in Heqo.
+ econstructor. constructor. econstructor. econstructor; eauto. constructor.
+ simpl; rewrite Heqo; simpl; eauto. constructor.
+ simpl. unfold Int64.loword. rewrite Int64.unsigned_repr, Int.repr_unsigned. auto.
+ assert (Int.modulus < Int64.max_unsigned) by (compute; auto).
+ generalize (Int.unsigned_range n). lia.
+- set (im := Int.repr Int.half_modulus).
set (fm := Float.of_intu im).
assert (eval_expr ge sp e m (Vfloat fm :: Vfloat f :: le) (Eletvar (S O)) (Vfloat f)).
constructor. auto.
@@ -889,11 +894,12 @@ Theorem eval_floatofint:
Proof.
intros until y. unfold floatofint. destruct (floatofint_match a); intros.
InvEval. TrivialExists.
- destruct Archi.ppc64.
- TrivialExists.
rename e0 into a. destruct x; simpl in H0; inv H0.
exists (Vfloat (Float.of_int i)); split; auto.
- set (t1 := addimm Float.ox8000_0000 a).
+ destruct Archi.ppc64.
+- rewrite Float.of_int_of_long.
+ EvalOp. constructor. EvalOp. simpl; eauto. constructor. auto.
+- set (t1 := addimm Float.ox8000_0000 a).
set (t2 := Eop Ofloatofwords (Eop (Ointconst Float.ox4330_0000) Enil ::: t1 ::: Enil)).
set (t3 := Eop (Ofloatconst (Float.from_words Float.ox4330_0000 Float.ox8000_0000)) Enil).
exploit (eval_addimm Float.ox8000_0000 le a). eauto. fold t1.
@@ -913,12 +919,12 @@ Theorem eval_floatofintu:
Proof.
intros until y. unfold floatofintu. destruct (floatofintu_match a); intros.
InvEval. TrivialExists.
- destruct Archi.ppc64.
- TrivialExists.
rename e0 into a. destruct x; simpl in H0; inv H0.
exists (Vfloat (Float.of_intu i)); split; auto.
- unfold floatofintu.
- set (t2 := Eop Ofloatofwords (Eop (Ointconst Float.ox4330_0000) Enil ::: a ::: Enil)).
+ destruct Archi.ppc64.
+- rewrite Float.of_intu_of_long.
+ EvalOp. constructor. EvalOp. simpl; eauto. constructor. auto.
+- set (t2 := Eop Ofloatofwords (Eop (Ointconst Float.ox4330_0000) Enil ::: a ::: Enil)).
set (t3 := Eop (Ofloatconst (Float.from_words Float.ox4330_0000 Int.zero)) Enil).
exploit (eval_subf le t2).
unfold t2. EvalOp. constructor. EvalOp. simpl; eauto. constructor. eauto. constructor.
diff --git a/powerpc/Stacklayout.v b/powerpc/Stacklayout.v
index cb3806bd..32b11ad5 100644
--- a/powerpc/Stacklayout.v
+++ b/powerpc/Stacklayout.v
@@ -77,11 +77,11 @@ Local Opaque Z.add Z.mul sepconj range.
set (ostkdata := align oendcs 8).
generalize b.(bound_local_pos) b.(bound_outgoing_pos) b.(bound_stack_data_pos); intros.
unfold fe_ofs_arg.
- assert (8 + 4 * b.(bound_outgoing) <= ol) by (apply align_le; omega).
- assert (ol <= ora) by (unfold ora; omega).
- assert (ora <= ocs) by (unfold ocs; omega).
+ assert (8 + 4 * b.(bound_outgoing) <= ol) by (apply align_le; lia).
+ assert (ol <= ora) by (unfold ora; lia).
+ assert (ora <= ocs) by (unfold ocs; lia).
assert (ocs <= oendcs) by (apply size_callee_save_area_incr).
- assert (oendcs <= ostkdata) by (apply align_le; omega).
+ assert (oendcs <= ostkdata) by (apply align_le; lia).
(* Reorder as:
back link
outgoing
@@ -90,12 +90,12 @@ Local Opaque Z.add Z.mul sepconj range.
callee-save *)
rewrite sep_swap3.
(* Apply range_split and range_split2 repeatedly *)
- apply range_drop_right with 8. omega.
- apply range_split. omega.
- apply range_split_2. fold ol; omega. omega.
- apply range_split. omega.
- apply range_split. omega.
- apply range_drop_right with ostkdata. omega.
+ apply range_drop_right with 8. lia.
+ apply range_split. lia.
+ apply range_split_2. fold ol; lia. lia.
+ apply range_split. lia.
+ apply range_split. lia.
+ apply range_drop_right with ostkdata. lia.
eapply sep_drop2. eexact H.
Qed.
@@ -112,12 +112,12 @@ Proof.
set (ostkdata := align oendcs 8).
generalize b.(bound_local_pos) b.(bound_outgoing_pos) b.(bound_stack_data_pos); intros.
unfold fe_ofs_arg.
- assert (8 + 4 * b.(bound_outgoing) <= ol) by (apply align_le; omega).
- assert (ol <= ora) by (unfold ora; omega).
- assert (ora <= ocs) by (unfold ocs; omega).
+ assert (8 + 4 * b.(bound_outgoing) <= ol) by (apply align_le; lia).
+ assert (ol <= ora) by (unfold ora; lia).
+ assert (ora <= ocs) by (unfold ocs; lia).
assert (ocs <= oendcs) by (apply size_callee_save_area_incr).
- assert (oendcs <= ostkdata) by (apply align_le; omega).
- split. omega. apply align_le. omega.
+ assert (oendcs <= ostkdata) by (apply align_le; lia).
+ split. lia. apply align_le. lia.
Qed.
Lemma frame_env_aligned:
@@ -136,10 +136,10 @@ Proof.
set (oendcs := size_callee_save_area b ocs).
set (ostkdata := align oendcs 8).
split. exists (fe_ofs_arg / 8); reflexivity.
- split. apply align_divides; omega.
- split. apply align_divides; omega.
+ split. apply align_divides; lia.
+ split. apply align_divides; lia.
split. apply Z.divide_0_r.
apply Z.divide_add_r.
- apply Z.divide_trans with 8. exists 2; auto. apply align_divides; omega.
+ apply Z.divide_trans with 8. exists 2; auto. apply align_divides; lia.
apply Z.divide_factor_l.
Qed.
diff --git a/powerpc/TargetPrinter.ml b/powerpc/TargetPrinter.ml
index 0f608d25..52d30e33 100644
--- a/powerpc/TargetPrinter.ml
+++ b/powerpc/TargetPrinter.ml
@@ -118,22 +118,16 @@ module Linux_System : SYSTEM =
let name_of_section = function
| Section_text -> ".text"
| Section_data i ->
- if i then
- ".data"
- else
- common_section ~sec:".section .bss" ()
+ variable_section ~sec:".data" ~bss:".section .bss" i
| Section_small_data i ->
- if i then
- ".section .sdata,\"aw\",@progbits"
- else
- common_section ~sec:".section .sbss,\"aw\",@nobits" ()
+ variable_section
+ ~sec:".section .sdata,\"aw\",@progbits"
+ ~bss:".section .sbss,\"aw\",@nobits"
+ i
| Section_const i ->
- if i || (not !Clflags.option_fcommon) then ".rodata" else "COMM"
+ variable_section ~sec:".rodata" i
| Section_small_const i ->
- if i || (not !Clflags.option_fcommon) then
- ".section .sdata2,\"a\",@progbits"
- else
- "COMM"
+ variable_section ~sec:".section .sdata2,\"a\",@progbits" i
| Section_string -> ".rodata"
| Section_literal -> ".section .rodata.cst8,\"aM\",@progbits,8"
| Section_jumptable -> ".text"
@@ -218,8 +212,10 @@ module Diab_System : SYSTEM =
let name_of_section = function
| Section_text -> ".text"
- | Section_data i -> if i then ".data" else common_section ()
- | Section_small_data i -> if i then ".sdata" else ".sbss"
+ | Section_data i ->
+ variable_section ~sec:".data" ~bss:".bss" i
+ | Section_small_data i ->
+ variable_section ~sec:".sdata" ~bss:".sbss" ~common:false i
| Section_const _ -> ".text"
| Section_small_const _ -> ".sdata2"
| Section_string -> ".text"
@@ -553,22 +549,16 @@ module Target (System : SYSTEM):TARGET =
fprintf oc " fadds %a, %a, %a\n" freg r1 freg r2 freg r3
| Pfcmpu(r1, r2) ->
fprintf oc " fcmpu %a, %a, %a\n" creg 0 freg r1 freg r2
- | Pfcfi(r1, r2) ->
- assert false
| Pfcfl(r1, r2) ->
assert false
| Pfcfid(r1, r2) ->
fprintf oc " fcfid %a, %a\n" freg r1 freg r2
- | Pfcfiu(r1, r2) ->
- assert false
| Pfcti(r1, r2) ->
assert false
| Pfctid(r1, r2) ->
assert false
| Pfctidz(r1, r2) ->
fprintf oc " fctidz %a, %a\n" freg r1 freg r2
- | Pfctiu(r1, r2) ->
- assert false
| Pfctiw(r1, r2) ->
fprintf oc " fctiw %a, %a\n" freg r1 freg r2
| Pfctiwz(r1, r2) ->
diff --git a/powerpc/ValueAOp.v b/powerpc/ValueAOp.v
index a270d857..c81f1a6c 100644
--- a/powerpc/ValueAOp.v
+++ b/powerpc/ValueAOp.v
@@ -133,9 +133,6 @@ Definition eval_static_operation (op: operation) (vl: list aval): aval :=
| Osingleoffloat, v1::nil => singleoffloat v1
| Ofloatofsingle, v1::nil => floatofsingle v1
| Ointoffloat, v1::nil => intoffloat v1
- | Ointuoffloat, v1::nil => intuoffloat v1
- | Ofloatofint, v1::nil => floatofint v1
- | Ofloatofintu, v1::nil => floatofintu v1
| Ofloatofwords, v1::v2::nil => floatofwords v1 v2
| Omakelong, v1::v2::nil => longofwords v1 v2
| Olowlong, v1::nil => loword v1
diff --git a/powerpc/extractionMachdep.v b/powerpc/extractionMachdep.v
index a3e945bf..202f4436 100644
--- a/powerpc/extractionMachdep.v
+++ b/powerpc/extractionMachdep.v
@@ -6,10 +6,11 @@
(* *)
(* Copyright Institut National de Recherche en Informatique et en *)
(* Automatique. All rights reserved. This file is distributed *)
-(* under the terms of the GNU General Public License as published by *)
-(* the Free Software Foundation, either version 2 of the License, or *)
-(* (at your option) any later version. This file is also distributed *)
-(* under the terms of the INRIA Non-Commercial License Agreement. *)
+(* under the terms of the GNU Lesser General Public License as *)
+(* published by the Free Software Foundation, either version 2.1 of *)
+(* the License, or (at your option) any later version. *)
+(* This file is also distributed under the terms of the *)
+(* INRIA Non-Commercial License Agreement. *)
(* *)
(* *********************************************************************)
@@ -21,6 +22,7 @@ Extract Constant Asm.high_half => "fun _ _ _ -> assert false".
Extract Constant Asm.symbol_is_small_data => "C2C.atom_is_small_data".
Extract Constant Asm.small_data_area_offset => "fun _ _ _ -> assert false".
Extract Constant Asm.symbol_is_rel_data => "C2C.atom_is_rel_data".
+Extract Constant Asm.symbol_is_aligned => "C2C.atom_is_aligned".
(* Suppression of stupidly big equality functions *)
Extract Constant Asm.ireg_eq => "fun (x: ireg) (y: ireg) -> x = y".