Skip to content

Commit

Permalink
Merge main
Browse files Browse the repository at this point in the history
  • Loading branch information
shigoel committed Mar 8, 2024
2 parents 83b419f + 67a1ce1 commit 265ecd2
Show file tree
Hide file tree
Showing 11 changed files with 296 additions and 54 deletions.
4 changes: 4 additions & 0 deletions Arm/Decode.lean
Original file line number Diff line number Diff line change
Expand Up @@ -100,10 +100,14 @@ def decode_data_proc_sfp (i : BitVec 32) : Option ArmInst :=
DPSFP (Advanced_simd_copy {Q, op, imm5, imm4, Rn, Rd})
| [0, Q:1, 101110, op2:2, 0, Rm:5, 0, imm4:4, 0, Rn:5, Rd:5] =>
DPSFP (Advanced_simd_extract {Q, op2, Rm, imm4, Rn, Rd})
| [0, Q:1, 001110, size:2, 0, Rm:5, 0, opcode:3, 10, Rn:5, Rd:5] =>
DPSFP (Advanced_simd_permute {Q, size, Rm, opcode, Rn, Rd})
| [0, Q:1, op:1, 0111100000, a:1, b:1, c:1, cmode:4, o2:1, 1, d:1, e:1, f:1, g:1, h:1, Rd:5] =>
DPSFP (Advanced_simd_modified_immediate {Q, op, a, b, c, cmode, o2, d, e, f, g, h, Rd})
| [01, op:1, 11110000, imm5:5, 0, imm4:4, 1, Rn:5, Rd:5] =>
DPSFP (Advanced_simd_scalar_copy {op, imm5, imm4, Rn, Rd})
| [0, Q:1, 001110, op2:2, 0, Rm:5, 0, len:2, op:1, 00, Rn:5, Rd:5] =>
DPSFP (Advanced_simd_table_lookup {Q, op2, Rm, len, op, Rn, Rd})
| [0, Q:1, U:1, 01110, size:2, 1, Rm:5, opcode:5, 1, Rn:5, Rd:5] =>
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] =>
Expand Down
43 changes: 43 additions & 0 deletions Arm/Decode/DPSFP.lean
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,25 @@ instance : ToString Advanced_simd_extract_cls where toString a := toString (repr
def Advanced_simd_extract_cls.toBitVec32 (x : Advanced_simd_extract_cls) : BitVec 32 :=
x._fixed1 ++ x.Q ++ x._fixed2 ++ x.op2 ++ x._fixed3 ++ x.Rm ++ x._fixed4 ++ x.imm4 ++ x._fixed5 ++ x.Rn ++ x.Rd

structure Advanced_simd_permute_cls where
_fixed1 : BitVec 1 := 0b0#1 -- [31:31]
Q : BitVec 1 -- [30:30]
_fixed2 : BitVec 6 := 0b001110#6 -- [29:24]
size : BitVec 2 -- [23:22]
_fixed3 : BitVec 1 := 0b0#1 -- [21:21]
Rm : BitVec 5 -- [20:16]
_fixed4 : BitVec 1 := 0b0#1 -- [15:15]
opcode : BitVec 3 -- [14:12]
_fixed5 : BitVec 2 := 0b10#2 -- [11:10]
Rn : BitVec 5 -- [9:5]
Rd : BitVec 5 -- [4:0]
deriving DecidableEq, Repr

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

def Advanced_simd_permute_cls.toBitVec32 (x : Advanced_simd_permute_cls) : BitVec 32 :=
x._fixed1 ++ x.Q ++ x._fixed2 ++ x.size ++ x._fixed3 ++ x.Rm ++ x._fixed4 ++ x.opcode ++ x._fixed5 ++ x.Rn ++ x.Rd

structure Advanced_simd_modified_immediate_cls where
_fixed1 : BitVec 1 := 0b0#1 -- [31:31]
Q : BitVec 1 -- [30:30]
Expand All @@ -165,6 +184,26 @@ instance : ToString Advanced_simd_modified_immediate_cls where toString a := toS
def Advanced_simd_modified_immediate_cls.toBitVec32 (x : Advanced_simd_modified_immediate_cls) : BitVec 32 :=
x._fixed1 ++ x.Q ++ x.op ++ x._fixed2 ++ x.a ++ x.b ++ x.c ++ x.cmode ++ x.o2 ++ x._fixed3 ++ x.d ++ x.e ++ x.f ++ x.g ++ x.h ++ x.Rd

structure Advanced_simd_table_lookup_cls where
_fixed1 : BitVec 1 := 0b0#1 -- [31:31]
Q : BitVec 1 -- [30:30]
_fixed2 : BitVec 6 := 0b001110#6 -- [29:24]
op2 : BitVec 2 -- [23:22]
_fixed3 : BitVec 1 := 0b0#1 -- [21:21]
Rm : BitVec 5 -- [20:16]
_fixed4 : BitVec 1 := 0b0#1 -- [15:15]
len : BitVec 2 -- [14:13]
op : BitVec 1 -- [12:12]
_fixed5 : BitVec 2 := 0b00#2 -- [11:10]
Rn : BitVec 5 -- [9:5]
Rd : BitVec 5 -- [4:0]
deriving DecidableEq, Repr

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

def Advanced_simd_table_lookup_cls.toBitVec32 (x : Advanced_simd_table_lookup_cls) : BitVec 32 :=
x._fixed1 ++ x.Q ++ x._fixed2 ++ x.op2 ++ x._fixed3 ++ x.Rm ++ x._fixed4 ++ x.len ++ x.op ++ x._fixed5 ++ x.Rn ++ x.Rd

structure Advanced_simd_three_same_cls where
_fixed1 : BitVec 1 := 0b0#1 -- [31:31]
Q : BitVec 1 -- [30:30]
Expand Down Expand Up @@ -237,10 +276,14 @@ inductive DataProcSFPInst where
Advanced_simd_copy_cls → DataProcSFPInst
| Advanced_simd_extract :
Advanced_simd_extract_cls → DataProcSFPInst
| Advanced_simd_permute :
Advanced_simd_permute_cls → DataProcSFPInst
| Advanced_simd_modified_immediate :
Advanced_simd_modified_immediate_cls → DataProcSFPInst
| Advanced_simd_scalar_copy :
Advanced_simd_scalar_copy_cls → DataProcSFPInst
| Advanced_simd_table_lookup :
Advanced_simd_table_lookup_cls → DataProcSFPInst
| Advanced_simd_three_same :
Advanced_simd_three_same_cls → DataProcSFPInst
| Advanced_simd_three_different :
Expand Down
4 changes: 4 additions & 0 deletions Arm/Exec.lean
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,14 @@ def exec_inst (ai : ArmInst) (s : ArmState) : ArmState :=
DPSFP.exec_advanced_simd_two_reg_misc i s
| DPSFP (DataProcSFPInst.Advanced_simd_extract i) =>
DPSFP.exec_advanced_simd_extract i s
| DPSFP (DataProcSFPInst.Advanced_simd_permute i) =>
DPSFP.exec_advanced_simd_permute i s
| DPSFP (DataProcSFPInst.Advanced_simd_modified_immediate i) =>
DPSFP.exec_advanced_simd_modified_immediate i s
| DPSFP (DataProcSFPInst.Advanced_simd_scalar_copy i) =>
DPSFP.exec_advanced_simd_scalar_copy i s
| DPSFP (DataProcSFPInst.Advanced_simd_table_lookup i) =>
DPSFP.exec_advanced_simd_table_lookup i s
| DPSFP (DataProcSFPInst.Advanced_simd_three_same i) =>
DPSFP.exec_advanced_simd_three_same i s
| DPSFP (DataProcSFPInst.Advanced_simd_three_different i) =>
Expand Down
24 changes: 24 additions & 0 deletions Arm/Insts/Common.lean
Original file line number Diff line number Diff line change
Expand Up @@ -344,4 +344,28 @@ example : rev_vector 32 16 8 0xaabbccdd#32 (by decide)
0xbbaaddcc#32 := by
native_decide

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

/-- Divide bv `vector` into elements, each of size `size`. This function gets
the `e`'th element from the `vector`. -/
@[state_simp_rules]
def elem_get (vector : BitVec n) (e : Nat) (size : Nat)
(h: size > 0): BitVec size :=
-- assert (e+1)*size <= n
let lo := e * size
let hi := lo + size - 1
have h : hi - lo + 1 = size := by simp only [hi, lo]; omega
h ▸ extractLsb hi lo vector

/-- Divide bv `vector` into elements, each of size `size`. This function sets
the `e`'th element in the `vector`. -/
@[state_simp_rules]
def elem_set (vector : BitVec n) (e : Nat) (size : Nat)
(value : BitVec size) (h: size > 0): BitVec n :=
-- assert (e+1)*size <= n
let lo := e * size
let hi := lo + size - 1
have h : hi - lo + 1 = size := by simp only [hi, lo]; omega
BitVec.partInstall hi lo (h ▸ value) vector

end Common
43 changes: 13 additions & 30 deletions Arm/Insts/DPSFP/Advanced_simd_copy.lean
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,7 @@ def dup_aux (e : Nat) (elements : Nat) (esize : Nat)
if h₀ : elements <= e then
result
else
let lo := e * esize
let hi := lo + esize -1
have h₁ : hi - lo + 1 = esize := by simp [hi, lo]; omega
let result := BitVec.partInstall hi lo (h₁ ▸ element) result
let result := elem_set result e esize element H
have h : elements - (e + 1) < elements - e := by omega
dup_aux (e + 1) elements esize element result H
termination_by (elements - e)
Expand All @@ -39,17 +36,14 @@ def exec_dup_element (inst : Advanced_simd_copy_cls) (s : ArmState) : ArmState :
let datasize := 64 <<< inst.Q.toNat
let elements := datasize / esize
let operand := read_sfp idxdsize inst.Rn s
let lo := index * esize
let hi := lo + esize - 1
let element := extractLsb hi lo operand
have h₀ : 0 < esize := by apply zero_lt_shift_left_pos (by decide)
have h₁ : hi - lo + 1 = esize := by simp [hi, lo]; omega
let result := dup_aux 0 elements esize (h₁ ▸ element) (BitVec.zero datasize) h₀
have h₀ : esize > 0 := by apply zero_lt_shift_left_pos (by decide)
let element := elem_get operand index esize h₀
let result := dup_aux 0 elements esize element (BitVec.zero datasize) h₀
-- State Updates
let s := write_pc ((read_pc s) + 4#64) s
let s := write_sfp datasize inst.Rd result s
s

def exec_dup_general (inst : Advanced_simd_copy_cls) (s : ArmState) : ArmState :=
let size := lowest_set_bit inst.imm5
if size > 3 || (size == 3 && inst.Q == 0) then
Expand Down Expand Up @@ -77,16 +71,9 @@ def exec_ins_element (inst : Advanced_simd_copy_cls) (s : ArmState) : ArmState :
let esize := 8 <<< size
let operand := read_sfp idxdsize inst.Rn s
let result := read_sfp 128 inst.Rd s
let lo_src := src_index * esize
let hi_src := lo_src + esize - 1
let elem := extractLsb hi_src lo_src operand
let lo_dst := dst_index * esize
let hi_dst := lo_dst + esize - 1
have h₀ : 0 < esize := by apply zero_lt_shift_left_pos (by decide)
have h : hi_dst - lo_dst + 1 = hi_src - lo_src + 1 := by
simp [hi_dst, lo_dst, hi_src, lo_src]
omega
let result := BitVec.partInstall hi_dst lo_dst (h ▸ elem) result
have h₀ : esize > 0 := by apply zero_lt_shift_left_pos (by decide)
let elem := elem_get operand src_index esize h₀
let result := elem_set result dst_index esize elem h₀
-- State Updates
let s := write_pc ((read_pc s) + 4#64) s
let s := write_sfp 128 inst.Rd result s
Expand All @@ -101,11 +88,8 @@ def exec_ins_general (inst : Advanced_simd_copy_cls) (s : ArmState) : ArmState :
let esize := 8 <<< size
let element := read_gpr esize inst.Rn s
let result := read_sfp 128 inst.Rd s
let lo := index * esize
let hi := lo + esize -1
have h₀ : 0 < esize := by apply zero_lt_shift_left_pos (by decide)
have h : hi - lo + 1 = esize := by simp [hi, lo]; omega
let result := BitVec.partInstall hi lo (h ▸ element) result
have h₀ : esize > 0 := by apply zero_lt_shift_left_pos (by decide)
let result := elem_set result index esize element h₀
-- State Updates
let s := write_pc ((read_pc s) + 4#64) s
let s := write_sfp 128 inst.Rd result s
Expand All @@ -125,9 +109,8 @@ def exec_smov_umov (inst : Advanced_simd_copy_cls) (s : ArmState) (signed : Bool
let idxdsize := 64 <<< (extractLsb 4 4 inst.imm5).toNat
-- if index == 0 then CheckFPEnabled64 else CheckFPAdvSIMDEnabled64
let operand := read_sfp idxdsize inst.Rn s
let lo := index * esize
let hi := lo + esize - 1
let element := extractLsb hi lo operand
have h₀ : esize > 0 := by apply zero_lt_shift_left_pos (by decide)
let element := elem_get operand index esize h₀
let result := if signed then signExtend datasize element else zeroExtend datasize element
-- State Updates
let s := write_pc ((read_pc s) + 4#64) s
Expand All @@ -144,7 +127,7 @@ def exec_advanced_simd_copy
| [_Q:1, 0, _imm5:5, 0111] => exec_smov_umov inst s false
| [1, 0, _imm5:5, 0011] => exec_ins_general inst s
| [1, 1, _imm5:5, _imm4:4] => exec_ins_element inst s
| _ => write_err (StateError.Illegal s!"Illegal {inst} encountered!") s
| _ => write_err (StateError.Unimplemented s!"Unsupported {inst} encountered!") s

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

Expand Down
99 changes: 99 additions & 0 deletions Arm/Insts/DPSFP/Advanced_simd_permute.lean
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
/-
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
-/
-- TRN1, TRN2

import Arm.Decode
import Arm.Insts.Common

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

namespace DPSFP

open BitVec

def trn_aux (p : Nat) (pairs : Nat) (esize : Nat) (part : Nat)
(operand1 : BitVec datasize) (operand2 : BitVec datasize)
(result : BitVec datasize) (h : esize > 0) : BitVec datasize :=
if h₀ : pairs <= p then
result
else
let idx_from := 2 * p + part
let op1_part := elem_get operand1 idx_from esize h
let op2_part := elem_get operand2 idx_from esize h
let result := elem_set result (2 * p) esize op1_part h
let result := elem_set result (2 * p + 1) esize op2_part h
have h₁ : pairs - (p + 1) < pairs - p := by omega
trn_aux (p + 1) pairs esize part operand1 operand2 result h
termination_by (pairs - p)

@[state_simp_rules]
def exec_trn (inst : Advanced_simd_permute_cls) (s : ArmState) : ArmState :=
if inst.size ++ inst.Q == 0b110#3 then
write_err (StateError.Illegal s!"Illegal {inst} encountered!") s
else
let esize := 8 <<< inst.size.toNat
let datasize := 64 <<< inst.Q.toNat
let elements := datasize / esize
let op := extractLsb 2 2 inst.opcode
let part := op.toNat
let pairs := elements / 2
let operand1 := read_sfp datasize inst.Rn s
let operand2 := read_sfp datasize inst.Rm s
have h : esize > 0 := by apply zero_lt_shift_left_pos (by decide)
let result := trn_aux 0 pairs esize part operand1 operand2 (BitVec.zero datasize) h
-- Update States
let s := write_sfp datasize inst.Rd result s
let s := write_pc ((read_pc s) + 4#64) s
s

@[state_simp_rules]
def exec_advanced_simd_permute
(inst : Advanced_simd_permute_cls) (s : ArmState) : ArmState :=
match inst.opcode with
| 0b010#3
| 0b110#3 => exec_trn inst s
| _ => write_err (StateError.Unimplemented s!"Unsupported {inst} encountered!") s

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

partial def Advanced_simd_permute_cls.trn1.rand : IO (Option (BitVec 32)) := do
let size := ← BitVec.rand 2
let Q := ← BitVec.rand 1
if size ++ Q == 0b110#3 then
Advanced_simd_permute_cls.trn1.rand
else
let (inst : Advanced_simd_permute_cls) :=
{ Q := Q,
size := size,
Rm := ← BitVec.rand 5,
opcode := 0b010#3,
Rn := ← BitVec.rand 5,
Rd := ← BitVec.rand 5
}
pure (some (inst.toBitVec32))

partial def Advanced_simd_permute_cls.trn2.rand : IO (Option (BitVec 32)) := do
let size := ← BitVec.rand 2
let Q := ← BitVec.rand 1
if size ++ Q == 0b110#3 then
Advanced_simd_permute_cls.trn2.rand
else
let (inst : Advanced_simd_permute_cls) :=
{ Q := Q,
size := size,
Rm := ← BitVec.rand 5,
opcode := 0b110#3,
Rn := ← BitVec.rand 5,
Rd := ← BitVec.rand 5
}
pure (some (inst.toBitVec32))

/-- Generate random instructions of Advanced_simd_permute class. -/
def Advanced_simd_permute_cls.rand : List (IO (Option (BitVec 32))) :=
[ Advanced_simd_permute_cls.trn1.rand,
Advanced_simd_permute_cls.trn2.rand ]

end DPSFP
11 changes: 4 additions & 7 deletions Arm/Insts/DPSFP/Advanced_simd_scalar_copy.lean
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,11 @@ def exec_advanced_simd_scalar_copy
let idxdsize := 64 <<< (extractLsb 4 4 inst.imm5).toNat
let esize := 8 <<< size
let operand := read_sfp idxdsize inst.Rn s
let lo := index.toNat * esize
let hi := lo + esize - 1
let result := extractLsb hi lo operand
have h₁ : 0 < esize := by apply zero_lt_shift_left_pos (by decide)
have h : hi - lo + 1 = esize := by simp [lo, hi]; omega
have h₁ : esize > 0 := by apply zero_lt_shift_left_pos (by decide)
let result := elem_get operand index.toNat esize h₁
-- State Updates
let s := write_pc ((read_pc s) + 4#64) s
let s := write_sfp esize inst.Rd (h ▸ result) s
let s := write_sfp esize inst.Rd result s
s

----------------------------------------------------------------------
Expand All @@ -44,7 +41,7 @@ partial def Advanced_simd_scalar_copy_cls.dup.rand : IO (Option (BitVec 32)) :=
Advanced_simd_scalar_copy_cls.dup.rand
else
let (inst : Advanced_simd_scalar_copy_cls) :=
{ op := 0b0#1,
{ op := 0b0#1,
imm5 := imm5,
imm4 := 0b0000#4,
Rn := ← BitVec.rand 5,
Expand Down
Loading

0 comments on commit 265ecd2

Please sign in to comment.