aboutsummaryrefslogtreecommitdiffstats
path: root/aarch64/Asmblock.v
diff options
context:
space:
mode:
Diffstat (limited to 'aarch64/Asmblock.v')
-rw-r--r--aarch64/Asmblock.v241
1 files changed, 128 insertions, 113 deletions
diff --git a/aarch64/Asmblock.v b/aarch64/Asmblock.v
index 1abe7d90..63d590e6 100644
--- a/aarch64/Asmblock.v
+++ b/aarch64/Asmblock.v
@@ -88,6 +88,19 @@ Inductive crbit: Type :=
Lemma crbit_eq: forall (x y: crbit), {x=y} + {x<>y}.
Proof. decide equality. Defined.
+Inductive dreg : Type :=
+ | DRSP: iregsp -> dreg
+ | DR0: ireg0 -> dreg
+ | DFR: freg -> dreg
+ .
+
+Coercion DRSP: iregsp >-> dreg.
+(* Causes ambiguity warning
+ * ireg can be coerced to either ireg0 or iregsp and both coerce to dreg
+ * However I also want to coerce both XZR and XSP to dreg *)
+Coercion DR0: ireg0 >-> dreg.
+Coercion DFR: freg >-> dreg.
+
(** We model the following registers of the ARM architecture. *)
Inductive preg: Type :=
@@ -199,7 +212,7 @@ Inductive cf_instruction : Type :=
| Ptbz (sz: isize) (r: ireg) (n: int) (lbl: label) (**r branch if bit n is zero *)
(** Pseudo-instructions *)
| Pbtbl (r1: ireg) (tbl: list label) (**r N-way branch through a jump table *)
- .
+ .
(*
A builtin is considered as a control-flow instruction, because it could emit a trace (cf. Machblock semantics).
@@ -284,7 +297,7 @@ Inductive arith_p : Type :=
| Pfmovimmd (f: float) (**r load float64 constant *)
.
-Inductive arith_comparison_p : Type :=
+Inductive arith_comparison_d : Type :=
(** Floating-point comparison *)
| Pfcmp0 (sz: fsize) (**r compare [r1] and [+0.0] *)
(** Integer arithmetic, immediate *)
@@ -294,7 +307,7 @@ Inductive arith_comparison_p : Type :=
| Ptstimm (sz: isize) (n: Z) (**r and, then set flags *)
.
-Inductive arith_pp : Type :=
+Inductive arith_pd : Type :=
(** Move integer register *)
| Pmov
(** Move wide immediate *)
@@ -332,25 +345,26 @@ Inductive arith_pp : Type :=
(** Integer arithmetic, immediate *)
| Paddimm (sz: isize) (n: Z) (**r addition *)
| Psubimm (sz: isize) (n: Z) (**r subtraction *)
+ (** Logical, immediate *)
+ | Pandimm (sz: isize) (n: Z) (**r and *)
+ | Peorimm (sz: isize) (n: Z) (**r xor *)
+ | Porrimm (sz: isize) (n: Z) (**r or *)
.
-Inductive arith_comparison_r0r : Type :=
- (** Integer arithmetic, shifted register *)
- | Pcmp (is:isize) (s: shift_op) (**r compare *)
- | Pcmn (is:isize) (s: shift_op) (**r compare negative *)
- (** Logical, shifted register *)
- | Ptst (is:isize) (s: shift_op) (**r and, then set flags *)
-.
-
-Inductive arith_comparison_pp : Type :=
+Inductive arith_comparison_dd : Type :=
(** Integer arithmetic, extending register *)
- | Pcmpext (x: extend_op) (**r int64-int32 cmp *)
- | Pcmnext (x: extend_op) (**r int64-int32 cmn *)
+ | Pcmpext (x: extend_op) (**r int64-int32 cmp *)
+ | Pcmnext (x: extend_op) (**r int64-int32 cmn *)
(** Floating-point comparison *)
| Pfcmp (sz: fsize) (**r compare [r1] and [r2] *)
+ (** Integer arithmetic, shifted register *)
+ | Pcmp (is:isize) (s: shift_op) (**r compare *)
+ | Pcmn (is:isize) (s: shift_op) (**r compare negative *)
+ (** Logical, shifted register *)
+ | Ptst (is:isize) (s: shift_op) (**r and, then set flags *)
.
-Inductive arith_ppp : Type :=
+Inductive arith_pdd : Type :=
(** Variable shifts *)
| Pasrv (sz: isize) (**r arithmetic right shift *)
| Plslv (sz: isize) (**r left shift *)
@@ -369,9 +383,6 @@ Inductive arith_ppp : Type :=
| Pfdiv (sz: fsize) (**r division *)
| Pfmul (sz: fsize) (**r multiplication *)
| Pfsub (sz: fsize) (**r subtraction *)
-.
-
-Inductive arith_rr0r : Type :=
(** Integer arithmetic, shifted register *)
| Padd (sz:isize) (s: shift_op) (**r addition *)
| Psub (sz:isize) (s: shift_op) (**r subtraction *)
@@ -384,15 +395,7 @@ Inductive arith_rr0r : Type :=
| Porn (sz:isize) (s: shift_op) (**r or-not *)
.
-
-Inductive arith_rr0 : Type :=
- (** Logical, immediate *)
- | Pandimm (sz: isize) (n: Z) (**r and *)
- | Peorimm (sz: isize) (n: Z) (**r xor *)
- | Porrimm (sz: isize) (n: Z) (**r or *)
-.
-
-Inductive arith_arrrr0 : Type :=
+Inductive arith_apddd : Type :=
(** Integer multiply/divide *)
| Pmadd (sz: isize) (**r multiply-add *)
| Pmsub (sz: isize) (**r multiply-sub *)
@@ -427,18 +430,15 @@ Inductive arith_arrrr0 : Type :=
*)
Inductive ar_instruction : Type :=
| PArithP (i : arith_p) (rd : preg)
- | PArithPP (i : arith_pp) (rd rs : preg)
- | PArithPPP (i : arith_ppp) (rd r1 r2 : preg)
- | PArithRR0R (i : arith_rr0r) (rd : ireg) (r1 : ireg0) (r2 : ireg)
- | PArithRR0 (i : arith_rr0) (rd : ireg) (r1 : ireg0)
- | PArithARRRR0 (i : arith_arrrr0) (rd r1 r2 : ireg) (r3 : ireg0)
+ | PArithPD (i : arith_pd) (rd : preg) (rs : dreg)
+ | PArithPDD (i : arith_pdd) (rd : preg) (r1 r2 : dreg)
+ | PArithAPDDD (i : arith_apddd) (rd : preg) (r1 r2 r3 : dreg)
(* Pfmadd and Pfmsub are currently not used by the semantics of aarch64/Asm
| PArithAPPPP (i : arith_apppp) (rd r1 r2 r3 : preg) *)
(* Pfnmadd and Pfnmsub are currently not used by the semantics of aarch64/Asm
| PArithAAPPPP (i : arith_aapppp) (rd r1 r2 r3 : preg) *)
- | PArithComparisonPP (i : arith_comparison_pp) (r1 r2 : preg)
- | PArithComparisonR0R (i : arith_comparison_r0r) (r1 : ireg0) (r2 : ireg)
- | PArithComparisonP (i : arith_comparison_p) (r1 : preg)
+ | PArithComparisonD (i : arith_comparison_d) (r1 : dreg)
+ | PArithComparisonDD (i : arith_comparison_dd) (r1 r2 : dreg)
(* Instructions without indirection sine they would be the only ones *)
(* PArithCP: Pcsetm is commented out by aarch64/Asm, so Pcset is alone *)
| Pcset (rd : ireg) (c : testcond) (**r set to 1/0 if cond is true/false *)
@@ -697,15 +697,23 @@ Definition genv := Genv.t fundef unit.
(** The value of an [ireg0] is either the value of the integer register,
or 0. *)
-Definition ir0 (is:isize) (rs: regset) (r: ireg0) : val :=
- match r with RR0 r => rs (IR r) | XZR => if is (* is W *) then Vint Int.zero else Vlong Int64.zero end.
+Definition dr (is:isize) (rs: regset) (dr: dreg) : val :=
+ match dr with
+ | DFR r => rs (FR r)
+ | DRSP r => rs (IR r)
+ | DR0 r0 =>
+ match r0 with
+ | RR0 r => rs (IR r)
+ | XZR => if is (* is W *) then Vint Int.zero else Vlong Int64.zero
+ end
+ end.
(** Concise notations for accessing and updating the values of registers. *)
Notation "a # b" := (a b) (at level 1, only parsing) : asm.
Notation "a # b <- c" := (Pregmap.set b c a) (at level 1, b at next level) : asm.
-Notation "a ## b" := (ir0 W a b) (at level 1, only parsing) : asm.
-Notation "a ### b" := (ir0 X a b) (at level 1, only parsing) : asm.
+Notation "a ## b" := (dr W a b) (at level 1, only parsing) : asm.
+Notation "a ### b" := (dr X a b) (at level 1, only parsing) : asm.
Open Scope asm.
@@ -1192,7 +1200,19 @@ Definition if_opt_bool_val (c: option bool) v1 v2: val :=
| None => Vundef
end.
-Definition arith_eval_pp i v :=
+Definition arith_pd_isize (i : arith_pd) :=
+ match i with
+ | Pandimm is _ | Peorimm is _ | Porrimm is _ => is
+ (* Arbitrary isize because in aarch64/Asm these instructions do not use an ireg0 *)
+ | Pmov | Pmovk _ _ _ | Paddadr _ _ | Psbfiz _ _ _
+ | Psbfx _ _ _ | Pubfiz _ _ _ | Pubfx _ _ _ | Pfmov
+ | Pfcvtds | Pfcvtsd | Pfabs _ | Pfneg _
+ | Pscvtf _ _ | Pucvtf _ _ | Pfcvtzs _ _ | Pfcvtzu _ _
+ | Paddimm _ _ | Psubimm _ _
+ => W
+ end.
+
+Definition arith_eval_pd i v :=
match i with
| Pmov => v
| Pmovk W n pos => insert_in_int v n pos 16
@@ -1233,9 +1253,28 @@ Definition arith_eval_pp i v :=
| Pucvtf D W => Val.maketotal (Val.floatofintu v)
| Pucvtf S X => Val.maketotal (Val.singleoflongu v)
| Pucvtf D X => Val.maketotal (Val.floatoflongu v)
+ | Pandimm W n => Val.and v (Vint (Int.repr n))
+ | Pandimm X n => Val.andl v (Vlong (Int64.repr n))
+ | Peorimm W n => Val.xor v (Vint (Int.repr n))
+ | Peorimm X n => Val.xorl v (Vlong (Int64.repr n))
+ | Porrimm W n => Val.or v (Vint (Int.repr n))
+ | Porrimm X n => Val.orl v (Vlong (Int64.repr n))
+ end.
+
+Definition arith_pdd_isize (i: arith_pdd) :=
+ match i with
+ | Padd is _ | Psub is _ | Pand is _ | Pbic is _
+ | Peon is _ | Peor is _ | Porr is _ | Porn is _
+ => is
+ (* Arbitrary isize because in aarch64/Asm these instructions do not use an ireg0 *)
+ | Pasrv _ | Plslv _ | Plsrv _ | Prorv _
+ | Psmulh | Pumulh | Psdiv _ | Pudiv _
+ | Paddext _ | Psubext _ | Pfadd _ | Pfdiv _
+ | Pfmul _ | Pfsub _
+ => W
end.
-Definition arith_eval_ppp i v1 v2 :=
+Definition arith_eval_pdd i v1 v2 :=
match i with
| Pasrv W => Val.shr v1 v2
| Pasrv X => Val.shrl v1 v2
@@ -1261,23 +1300,6 @@ Definition arith_eval_ppp i v1 v2 :=
| Pfmul D => Val.mulf v1 v2
| Pfsub S => Val.subfs v1 v2
| Pfsub D => Val.subf v1 v2
- end.
-
-Definition arith_rr0r_isize (i: arith_rr0r) :=
- match i with
- | Padd is _ => is
- | Psub is _ => is
- | Pand is _ => is
- | Pbic is _ => is
- | Peon is _ => is
- | Peor is _ => is
- | Porr is _ => is
- | Porn is _ => is
- end.
-
-(* obtain v1 by [ir0 (arith_rr0r_isize i) rs s1] *)
-Definition arith_eval_rr0r i v1 v2 :=
- match i with
| Padd W s => Val.add v1 (eval_shift_op_int v2 s)
| Padd X s => Val.addl v1 (eval_shift_op_long v2 s)
| Psub W s => Val.sub v1 (eval_shift_op_int v2 s)
@@ -1296,29 +1318,12 @@ Definition arith_eval_rr0r i v1 v2 :=
| Porn X s => Val.orl v1 (Val.notl (eval_shift_op_long v2 s))
end.
-Definition arith_rr0_isize (i : arith_rr0) :=
- match i with
- | Pandimm is _ | Peorimm is _ | Porrimm is _ => is
- end.
-
-(* obtain v by [ir0 (arith_rr0_isize i) rs s] *)
-Definition arith_eval_rr0 i v :=
- match i with
- | Pandimm W n => Val.and v (Vint (Int.repr n))
- | Pandimm X n => Val.andl v (Vlong (Int64.repr n))
- | Peorimm W n => Val.xor v (Vint (Int.repr n))
- | Peorimm X n => Val.xorl v (Vlong (Int64.repr n))
- | Porrimm W n => Val.or v (Vint (Int.repr n))
- | Porrimm X n => Val.orl v (Vlong (Int64.repr n))
- end.
-
-Definition arith_arrrr0_isize (i : arith_arrrr0) :=
+Definition arith_apddd_isize (i : arith_apddd) :=
match i with
| Pmadd is | Pmsub is => is
end.
-(* obtain v3 by [ir0 (arith_arrrr0_isize i) rs s3] *)
-Definition arith_eval_arrrr0 i v1 v2 v3 :=
+Definition arith_eval_apddd i v1 v2 v3 :=
match i with
| Pmadd W => Val.add v3 (Val.mul v1 v2)
| Pmadd X => Val.addl v3 (Val.mull v1 v2)
@@ -1326,22 +1331,20 @@ Definition arith_eval_arrrr0 i v1 v2 v3 :=
| Pmsub X => Val.subl v3 (Val.mull v1 v2)
end.
-Definition arith_prepare_comparison_pp i (v1 v2 : val) :=
+Definition arith_comparison_dd_isize i :=
match i with
- | Pcmpext x => (v1, (eval_extend v2 x))
- | Pcmnext x => (v1, (Val.negl (eval_extend v2 x)))
- | Pfcmp _ => (v1, v2)
+ | Pcmp is _ | Pcmn is _ | Ptst is _
+ => is
+ (* Arbitrary isize because in aarch64/Asm these instructions do not use an ireg0 *)
+ | Pcmpext _ | Pcmnext _ | Pfcmp _
+ => W
end.
-Definition arith_comparison_r0r_isize i :=
- match i with
- | Pcmp is _ => is
- | Pcmn is _ => is
- | Ptst is _ => is
- end.
-
-Definition arith_prepare_comparison_r0r i v1 v2 :=
+Definition arith_prepare_comparison_dd i (v1 v2 : val) :=
match i with
+ | Pcmpext x => (v1, (eval_extend v2 x))
+ | Pcmnext x => (v1, (Val.negl (eval_extend v2 x)))
+ | Pfcmp _ => (v1, v2)
| Pcmp W s => (v1, (eval_shift_op_int v2 s))
| Pcmp X s => (v1, (eval_shift_op_long v2 s))
| Pcmn W s => (v1, (Val.neg (eval_shift_op_int v2 s)))
@@ -1350,7 +1353,14 @@ Definition arith_prepare_comparison_r0r i v1 v2 :=
| Ptst X s => ((Val.andl v1 (eval_shift_op_long v2 s)), (Vlong Int64.zero))
end.
-Definition arith_prepare_comparison_p i v :=
+Definition arith_comparison_d_isize i :=
+ match i with
+ (* Arbitrary isize because in aarch64/Asm these instructions do not use an ireg0 *)
+ | Pcmpimm _ _ | Pcmnimm _ _ | Ptstimm _ _ | Pfcmp0 _
+ => W
+ end.
+
+Definition arith_prepare_comparison_d i v :=
match i with
| Pcmpimm W n => (v, (Vint (Int.repr n)))
| Pcmpimm X n => (v, (Vlong (Int64.repr n)))
@@ -1362,14 +1372,17 @@ Definition arith_prepare_comparison_p i v :=
| Pfcmp0 D => (v, (Vfloat Float.zero))
end.
-Definition arith_comparison_pp_compare i :=
+Definition arith_comparison_dd_compare i :=
match i with
- | Pcmpext _ | Pcmnext _ => compare_long
+ | Pcmp W _ | Pcmn W _ | Ptst W _
+ => compare_int
+ | Pcmp X _ | Pcmn X _ | Ptst X _ | Pcmpext _ | Pcmnext _
+ => compare_long
| Pfcmp S => compare_single
| Pfcmp D => compare_float
end.
-Definition arith_comparison_p_compare i :=
+Definition arith_comparison_d_compare i :=
match i with
| Pcmpimm W _ | Pcmnimm W _ | Ptstimm W _ => compare_int
| Pcmpimm X _ | Pcmnimm X _ | Ptstimm X _ => compare_long
@@ -1380,26 +1393,28 @@ Definition arith_comparison_p_compare i :=
Definition exec_arith_instr (ai: ar_instruction) (rs: regset): regset :=
match ai with
| PArithP i d => rs#d <- (arith_eval_p i)
- | PArithPP i d s => rs#d <- (arith_eval_pp i rs#s)
- | PArithPPP i d s1 s2 => rs#d <- (arith_eval_ppp i rs#s1 rs#s2)
-
- | PArithRR0R i d s1 s2 => rs#d <- (arith_eval_rr0r i (ir0 (arith_rr0r_isize i) rs s1) rs#s2)
-
- | PArithRR0 i d s => rs#d <- (arith_eval_rr0 i (ir0 (arith_rr0_isize i) rs s))
-
- | PArithARRRR0 i d s1 s2 s3 =>
- rs#d <- (arith_eval_arrrr0 i rs#s1 rs#s2 (ir0 (arith_arrrr0_isize i) rs s3))
-
- | PArithComparisonPP i s1 s2 =>
- let (v1, v2) := arith_prepare_comparison_pp i rs#s1 rs#s2 in
- arith_comparison_pp_compare i rs v1 v2
- | PArithComparisonR0R i s1 s2 =>
- let is := arith_comparison_r0r_isize i in
- let (v1, v2) := arith_prepare_comparison_r0r i (ir0 is rs s1) rs#s2 in
- (if is (* is W *) then compare_int else compare_long) rs v1 v2
- | PArithComparisonP i s =>
- let (v1, v2) := arith_prepare_comparison_p i rs#s in
- arith_comparison_p_compare i rs v1 v2
+ | PArithPD i d s =>
+ let is := arith_pd_isize i in
+ let get_val := (dr is rs) in
+ rs#d <- (arith_eval_pd i (get_val s))
+ | PArithPDD i d s1 s2 =>
+ let is := arith_pdd_isize i in
+ let get_val := (dr is rs) in
+ rs#d <- (arith_eval_pdd i (get_val s1) (get_val s2))
+ | PArithAPDDD i d s1 s2 s3 =>
+ let is := arith_apddd_isize i in
+ let get_val := (dr is rs) in
+ rs#d <- (arith_eval_apddd i (get_val s1) (get_val s2) (get_val s3))
+ | PArithComparisonDD i s1 s2 =>
+ let is := arith_comparison_dd_isize i in
+ let get_val := (dr is rs) in
+ let (v1, v2) := arith_prepare_comparison_dd i (get_val s1) (get_val s2) in
+ arith_comparison_dd_compare i rs v1 v2
+ | PArithComparisonD i s =>
+ let is := arith_comparison_d_isize i in
+ let get_val := (dr is rs) in
+ let (v1, v2) := arith_prepare_comparison_d i (get_val s) in
+ arith_comparison_d_compare i rs v1 v2
| Pcset d c => rs#d <- (if_opt_bool_val (eval_testcond c rs) (Vint Int.one) (Vint Int.zero))
| Pfmovi S d s => rs#d <- (float32_of_bits rs##s)
| Pfmovi D d s => rs#d <- (float64_of_bits rs###s)