------------------------------------------------------------------------ -- Agda Helium -- -- Definition of instructions using the Armv8-M pseudocode. ------------------------------------------------------------------------ {-# OPTIONS --safe --without-K #-} module Helium.Instructions.Base where open import Data.Bool as Bool using (true; false) open import Data.Fin as Fin using (Fin; Fin′; zero; suc; toℕ) open import Data.Fin.Patterns open import Data.Integer as ℤ using (1ℤ; 0ℤ; -1ℤ) open import Data.Nat as ℕ using (ℕ; zero; suc) import Data.Nat.Properties as ℕₚ open import Data.Product using (uncurry) open import Data.Sum using ([_,_]′; inj₂) open import Data.Vec as Vec using (Vec; []; _∷_) open import Data.Vec.Relation.Unary.All using (All; []; _∷_) open import Function using (_$_) open import Helium.Data.Pseudocode.Core as Core public import Helium.Instructions.Core as Instr import Relation.Binary.PropositionalEquality as P open import Relation.Nullary.Decidable.Core using (True) private variable k m n : ℕ t : Type Γ : Vec Type n --- Types beat : Type beat = fin 4 elmtMask : Type elmtMask = bits 4 --- State State : Vec Type _ State = array (bits 32) 32 -- S ∷ array (bits 32) 16 -- R ∷ bits 16 -- VPR-P0 ∷ bits 8 -- VPR-mask ∷ bit -- FPSCR-QC ∷ bool -- _AdvanceVPTState ∷ beat -- _BeatId ∷ [] --- References -- Direct from State S : Reference State Γ (array (bits 32) 32) S = state 0F R : Reference State Γ (array (bits 32) 16) R = state 1F VPR-P0 : Reference State Γ (bits 16) VPR-P0 = state 2F VPR-mask : Reference State Γ (bits 8) VPR-mask = state 3F FPSCR-QC : Reference State Γ bit FPSCR-QC = state 4F AdvanceVPTState : Reference State Γ bool AdvanceVPTState = state 5F BeatId : Reference State Γ beat BeatId = state 6F -- Indirect index : Expression State Γ (array t (suc m)) → Expression State Γ (fin (suc m)) → Expression State Γ t index {m = m} x i = unbox (slice (cast (ℕₚ.+-comm 1 m) x) i) *index : Reference State Γ (array t (suc m)) → Expression State Γ (fin (suc m)) → Reference State Γ t *index {m = m} x i = unbox (slice (cast (ℕₚ.+-comm 1 m) x) i) *index-group : Reference State Γ (array t (k ℕ.* suc m)) → Expression State Γ (fin (suc m)) → Reference State Γ (array t k) *index-group {k = k} {m = m} x i = slice (cast eq x) (fin reindex (tup (i ∷ []))) where eq = P.trans (ℕₚ.*-comm k (suc m)) (ℕₚ.+-comm k (m ℕ.* k)) reindex : ∀ {m n} → Fin (suc m) → Fin (suc (m ℕ.* n)) reindex {m} {n} 0F = Fin.inject+ (m ℕ.* n) 0F reindex {suc m} {n} (suc i) = Fin.cast (ℕₚ.+-suc n (m ℕ.* n)) (Fin.raise n (reindex i)) index-group : Expression State Γ (array t (k ℕ.* suc m)) → Expression State Γ (fin (suc m)) → Expression State Γ (array t k) index-group {k = k} {m = m} x i = slice (cast eq x) (fin reindex (tup (i ∷ []))) where eq = P.trans (ℕₚ.*-comm k (suc m)) (ℕₚ.+-comm k (m ℕ.* k)) reindex : ∀ {m n} → Fin (suc m) → Fin (suc (m ℕ.* n)) reindex {m} {n} 0F = Fin.inject+ (m ℕ.* n) 0F reindex {suc m} {n} (suc i) = Fin.cast (ℕₚ.+-suc n (m ℕ.* n)) (Fin.raise n (reindex i)) Q[_,_] : Expression State Γ (fin 8) → Expression State Γ (fin 4) → Reference State Γ (bits 32) Q[ i , j ] = *index S (fin (uncurry Fin.combine) (tup (i ∷ j ∷ []))) elem : ∀ m → Expression State Γ (array t (suc k ℕ.* m)) → Expression State Γ (fin (suc k)) → Expression State Γ (array t m) elem {k = k} zero x i = cast (ℕₚ.*-comm k 0) x elem {k = k} (suc m) x i = index-group (cast (ℕₚ.*-comm (suc k) (suc m)) x) i *elem : ∀ m → Reference State Γ (array t (suc k ℕ.* m)) → Expression State Γ (fin (suc k)) → Reference State Γ (array t m) *elem {k = k} zero x i = cast (ℕₚ.*-comm k 0) x *elem {k = k} (suc m) x i = *index-group (cast (ℕₚ.*-comm (suc k) (suc m)) x) i --- Other utiliies hasBit : Expression State Γ (bits (suc m)) → Expression State Γ (fin (suc m)) → Expression State Γ bool hasBit {n} x i = index x i ≟ lit true sliceⁱ : ℕ → Expression State Γ int → Expression State Γ (bits m) sliceⁱ {m = zero} n i = lit [] sliceⁱ {m = suc m} n i = sliceⁱ (suc n) i ∶ [ getBit n i ] --- Functions Int : Function State (bits n ∷ bool ∷ []) int Int = skip ∙return (if var 1F then uint (var 0F) else sint (var 0F)) -- arguments swapped, pred n SignedSatQ : ∀ n → Function State (int ∷ []) (tuple (bits (suc n) ∷ bool ∷ [])) SignedSatQ n = declare (lit true) ( if max >3 (tup ((var 3F) ∷ []))) then FPSCR-QC ≔ lit true))) where open Instr.VecOp₂ d e*esize>>3 : Fin (toℕ elements) → Fin 4 e*esize>>3 x = helper size x where helper : ∀ size → Fin′ (Instr.Size.elements size) → Fin 4 helper Instr.8bit i = Fin.combine i (zero {0}) helper Instr.16bit i = Fin.combine i (zero {1}) helper Instr.32bit i = Fin.combine i zero vqdmulh : Instr.VQDMulH → Procedure State [] vqdmulh d = vqr?dmulh d (skip ∙return lit (ℤ.+ 2) * var 0F * var 1F >> toℕ esize) where open Instr.VecOp₂ d using (esize) vqrdmulh : Instr.VQRDMulH → Procedure State [] vqrdmulh d = vqr?dmulh d (skip ∙return lit (ℤ.+ 2) * var 0F * var 1F + lit 1ℤ << toℕ esize-1 >> toℕ esize) where open Instr.VecOp₂ d using (esize; esize-1)