Skip to content

Commit

Permalink
Merge pull request #19 from pennyannn/yppe/fmov_general
Browse files Browse the repository at this point in the history
Add Conversion_between_FP_and_Int_cls for FMOV (general)
  • Loading branch information
shigoel authored Feb 27, 2024
2 parents 9fc7c4b + d6f7592 commit 3fc5b4f
Show file tree
Hide file tree
Showing 7 changed files with 186 additions and 4 deletions.
19 changes: 19 additions & 0 deletions Arm/Decode.lean
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,8 @@ def decode_data_proc_sfp (i : BitVec 32) : Option ArmInst :=
DPSFP (Advanced_simd_three_same {Q, U, size, Rm, opcode, Rn, Rd})
| [0, Q:1, U:1, 01110, size:2, 1, Rm:5, opcode:4, 00, Rn:5, Rd:5] =>
DPSFP (Advanced_simd_three_different {Q, U, size, Rm, opcode, Rn, Rd})
| [sf:1, 0, S:1, 11110, ftype:2, 1, rmode:2, opcode:3, 000000, Rn:5, Rd:5] =>
DPSFP (Conversion_between_FP_and_Int {sf, S, ftype, rmode, opcode, Rn, Rd})
| _ => none

def decode_ldst_inst (i : BitVec 32) : Option ArmInst :=
Expand Down Expand Up @@ -441,6 +443,23 @@ example : decode_raw_inst 0x6e026e2a =
Rd := 0x0a#5 })) := by
rfl

-- fmov v25.d[1], x5
example : decode_raw_inst 0x9eaf00b9 =
(ArmInst.DPSFP
(DataProcSFPInst.Conversion_between_FP_and_Int
{ sf := 0x1#1,
_fixed1 := 0x0#1,
S := 0x0#1,
_fixed2 := 0x1e#5,
ftype := 0x2#2,
_fixed3 := 0x1#1,
rmode := 0x1#2,
opcode := 0x7#3,
_fixed4 := 0x00#6,
Rn := 0x05#5,
Rd := 0x19#5 })) := by
rfl

-- Unimplemented
example : decode_raw_inst 0x00000000#32 = none := by rfl

Expand Down
21 changes: 21 additions & 0 deletions Arm/Decode/DPSFP.lean
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,25 @@ instance : ToString Advanced_simd_three_different_cls where toString a := toStri
def Advanced_simd_three_different_cls.toBitVec32 (x : Advanced_simd_three_different_cls) : BitVec 32 :=
x._fixed1 ++ x.Q ++ x.U ++ x._fixed2 ++ x.size ++ x._fixed3 ++ x.Rm ++ x.opcode ++ x._fixed4 ++ x.Rn ++ x.Rd

structure Conversion_between_FP_and_Int_cls where
sf : BitVec 1 -- [31:31]
_fixed1 : BitVec 1 := 0b0#1 -- [30:30]
S : BitVec 1 -- [29:29]
_fixed2 : BitVec 5 := 0b11110#5 -- [28:24]
ftype : BitVec 2 -- [23:22]
_fixed3 : BitVec 1 := 0b1#1 -- [21:21]
rmode : BitVec 2 -- [20:19]
opcode : BitVec 3 -- [18:16]
_fixed4 : BitVec 6 := 0b000000#6 -- [15:10]
Rn : BitVec 5 -- [9:5]
Rd : BitVec 5 -- [4:0]
deriving DecidableEq, Repr

instance : ToString Conversion_between_FP_and_Int_cls where toString a := toString (repr a)

def Conversion_between_FP_and_Int_cls.toBitVec32 (x : Conversion_between_FP_and_Int_cls) : BitVec 32 :=
x.sf ++ x._fixed1 ++ x.S ++ x._fixed2 ++ x.ftype ++ x._fixed3 ++ x.rmode ++ x.opcode ++ x._fixed4 ++ x.Rn ++ x.Rd

inductive DataProcSFPInst where
| Crypto_aes :
Crypto_aes_cls → DataProcSFPInst
Expand All @@ -226,6 +245,8 @@ inductive DataProcSFPInst where
Advanced_simd_three_same_cls → DataProcSFPInst
| Advanced_simd_three_different :
Advanced_simd_three_different_cls → DataProcSFPInst
| Conversion_between_FP_and_Int :
Conversion_between_FP_and_Int_cls → DataProcSFPInst
deriving DecidableEq, Repr

instance : ToString DataProcSFPInst where toString a := toString (repr a)
Expand Down
2 changes: 2 additions & 0 deletions Arm/Exec.lean
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ def exec_inst (ai : ArmInst) (s : ArmState) : ArmState :=
DPSFP.exec_advanced_simd_three_same i s
| DPSFP (DataProcSFPInst.Advanced_simd_three_different i) =>
DPSFP.exec_advanced_simd_three_different i s
| DPSFP (DataProcSFPInst.Conversion_between_FP_and_Int i) =>
DPSFP.exec_conversion_between_FP_and_Int i s

| LDST (LDSTInst.Reg_imm_post_indexed i) =>
LDST.exec_reg_imm_post_indexed i s
Expand Down
27 changes: 26 additions & 1 deletion Arm/Insts/Common.lean
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ instance : ToString SIMDThreeSameLogicalType where toString a := toString (repr
----------------------------------------------------------------------

@[simp]
def Vpart (n : BitVec 5) (part : Nat) (width : Nat) (s : ArmState) (H : width > 0)
def Vpart_read (n : BitVec 5) (part width : Nat) (s : ArmState) (H : width > 0)
: BitVec width :=
-- assert n >= 0 && n <= 31;
-- assert part IN {0, 1};
Expand All @@ -210,6 +210,20 @@ def Vpart (n : BitVec 5) (part : Nat) (width : Nat) (s : ArmState) (H : width >
-- assert width IN {32,64};
h2 ▸ extractLsb (width*2-1) width $ read_sfp 128 n s


@[simp]
def Vpart_write (n : BitVec 5) (part width : Nat) (val : BitVec width) (s : ArmState)
: ArmState :=
-- assert n >= 0 && n <= 31;
-- assert part IN {0, 1};
if part == 0 then
-- assert width < 128
write_sfp width n val s
else
-- assert width == 64
let res := (extractLsb 63 0 val) ++ (read_sfp 64 n s)
write_sfp 128 n res s

----------------------------------------------------------------------

@[simp]
Expand All @@ -233,4 +247,15 @@ theorem esize_gt_zero (size : Nat):
simp_all only [ Nat.shiftLeft_eq, gt_iff_lt, Nat.zero_lt_succ
, mul_pos_iff_of_pos_left, zero_lt_two, pow_pos]

----------------------------------------------------------------------

-- Floating-point convert/move instruction types
inductive FPConvOp where
| FPConvOp_CVT_FtoI : FPConvOp
| FPConvOp_CVT_ItoF : FPConvOp
| FPConvOp_MOV_FtoI : FPConvOp
| FPConvOp_MOV_ItoF : FPConvOp
| FPConvOp_CVT_FtoI_JS : FPConvOp
deriving DecidableEq, Repr

end Common
4 changes: 2 additions & 2 deletions Arm/Insts/DPSFP/Advanced_simd_three_different.lean
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,8 @@ def exec_pmull (inst : Advanced_simd_three_different_cls) (s : ArmState) : ArmSt
let part := inst.Q.toNat
let elements := datasize / esize
have h₁ : datasize > 0 := by decide
let operand1 := Vpart inst.Rn part datasize s h₁
let operand2 := Vpart inst.Rm part datasize s h₁
let operand1 := Vpart_read inst.Rn part datasize s h₁
let operand2 := Vpart_read inst.Rm part datasize s h₁
let result :=
pmull_op 0 esize elements operand1 operand2 (Std.BitVec.zero (2*datasize)) h₀
let s := write_sfp (datasize*2) inst.Rd result s
Expand Down
113 changes: 113 additions & 0 deletions Arm/Insts/DPSFP/Conversion_between_FP_and_Int.lean
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
/-
Copyright (c) 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Author(s): Yan Peng
-/
-- FMOV (general)

import Arm.Decode
import Arm.Insts.Common
import Arm.BitVec

----------------------------------------------------------------------

namespace DPSFP

open Std.BitVec

@[simp]
def fmov_general_aux (intsize : Nat) (fltsize : Nat) (op : FPConvOp)
(part : Nat) (inst : Conversion_between_FP_and_Int_cls) (s : ArmState)
(H : 0 < fltsize)
: ArmState :=
-- Assume CheckFPEnabled64()
match op with
| FPConvOp.FPConvOp_MOV_FtoI =>
let fltval := Vpart_read inst.Rn part fltsize s H
let intval := zeroExtend intsize fltval
-- State Update
let s := write_gpr intsize inst.Rd intval s
let s := write_pc ((read_pc s) + 4#64) s
s
| FPConvOp.FPConvOp_MOV_ItoF =>
let intval := read_gpr intsize inst.Rn s
let fltval := extractLsb (fltsize - 1) 0 intval
-- State Update
have h₀ : fltsize - 1 - 0 + 1 = fltsize := by omega
let s := Vpart_write inst.Rd part fltsize (h₀ ▸ fltval) s
let s := write_pc ((read_pc s) + 4#64) s
s
| _ => write_err (StateError.Other s!"fmov_general_aux called with non-FMOV op!") s

@[simp]
def exec_fmov_general
(inst : Conversion_between_FP_and_Int_cls) (s : ArmState): ArmState :=
let intsize := 32 <<< inst.sf.toNat
let decode_fltsize := if inst.ftype == 0b10#2 then 64 else (8 <<< (inst.ftype ^^^ 0b10#2).toNat)
have H: 0 < decode_fltsize := by
simp only [beq_iff_eq]
split
· decide
· generalize Std.BitVec.toNat (inst.ftype ^^^ 2#2) = x
apply esize_gt_zero
match (extractLsb 2 1 inst.opcode) ++ inst.rmode with
| 1100 => -- FMOV
if decode_fltsize != 16 && decode_fltsize != intsize then
write_err (StateError.Illegal s!"Illegal {inst} encountered!") s
else
let op := if extractLsb 0 0 inst.opcode == 1
then FPConvOp.FPConvOp_MOV_ItoF
else FPConvOp.FPConvOp_MOV_FtoI
let part := 0
fmov_general_aux intsize decode_fltsize op part inst s H
| 1101 => -- FMOV D[1]
if intsize != 64 || inst.ftype != 0b10#2 then
write_err (StateError.Illegal s!"Illegal {inst} encountered!") s
else
let op := if extractLsb 0 0 inst.opcode == 1
then FPConvOp.FPConvOp_MOV_ItoF
else FPConvOp.FPConvOp_MOV_FtoI
let part := 1
fmov_general_aux intsize decode_fltsize op part inst s H
| _ => write_err (StateError.Other s!"exec_fmov_general called with non-FMOV instructions!") s

@[simp]
def exec_conversion_between_FP_and_Int
(inst : Conversion_between_FP_and_Int_cls) (s : ArmState) : ArmState :=
if inst.ftype == 0b10#2 && (extractLsb 2 1 inst.opcode) ++ inst.rmode != 0b1101#4 then
write_err (StateError.Illegal s!"Illegal {inst} encountered!") s
-- Assume IsFeatureImplemented(FEAT_FP16) is true
else
match_bv inst.sf ++ inst.S ++ inst.ftype ++ inst.rmode ++ inst.opcode with
| [_sf:1, 0, _ftype:2, 0, _rmode0:1, 11, _opcode0:1] => exec_fmov_general inst s
| _ => write_err (StateError.Unimplemented s!"Unsupported instruction {inst} encountered!") s

----------------------------------------------------------------------

partial def Conversion_between_FP_and_Int_cls.fmov_general.rand : IO (Option (BitVec 32)) := do
let ftype := ← BitVec.rand 2
let rmode := ← (0b0#1 ++ ·) <$> BitVec.rand 1
let opcode := ← (0b11#2++ ·) <$> BitVec.rand 1
let sf := ← BitVec.rand 1
let intsize := 32 <<< sf.toNat
let decode_fltsize := if ftype == 0b10#2 then 64 else (8 <<< (ftype ^^^ 0b10#2).toNat)
if ftype == 0b10#2 && (extractLsb 2 1 opcode) ++ rmode != 0b1101#4
|| decode_fltsize != 16 && decode_fltsize != intsize
|| intsize != 64 || ftype != 0b10#2 then
Conversion_between_FP_and_Int_cls.fmov_general.rand
else
let (inst : Conversion_between_FP_and_Int_cls) :=
{ sf := sf,
S := 0b0#1,
ftype := ftype,
rmode := rmode,
opcode := opcode,
Rn := ← BitVec.rand 5,
Rd := ← BitVec.rand 5 }
pure (inst.toBitVec32)

/-- Generate random instructions of Conversion_between_FP_and_Int class. -/
def Conversion_between_FP_and_Int_cls.rand : List (IO (Option (BitVec 32))) :=
[ Conversion_between_FP_and_Int_cls.fmov_general.rand ]

end DPSFP
4 changes: 3 additions & 1 deletion Arm/Insts/DPSFP/Insts.lean
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import Arm.Insts.DPSFP.Crypto_aes
import Arm.Insts.DPSFP.Crypto_two_reg_sha512
import Arm.Insts.DPSFP.Crypto_three_reg_sha512
import Arm.Insts.DPSFP.Crypto_four_reg
import Arm.Insts.DPSFP.Conversion_between_FP_and_Int

/-- List of functions to generate random instructions of the
DPSFP class. -/
Expand All @@ -27,4 +28,5 @@ def DPSFP.rand : List (IO (Option (BitVec 32))) :=
DPSFP.Advanced_simd_two_reg_misc_cls.rand ++
DPSFP.Crypto_three_reg_sha512_cls.rand ++
DPSFP.Crypto_two_reg_sha512_cls.rand ++
DPSFP.Crypto_four_reg_cls.rand
DPSFP.Crypto_four_reg_cls.rand ++
DPSFP.Conversion_between_FP_and_Int_cls.rand

0 comments on commit 3fc5b4f

Please sign in to comment.