{-# OPTIONS_HADDOCK prune #-}

-- |
-- Module: Vestigia.Contract.Types
-- Copyright: (c) 2026 Jared Tobin
-- License: MIT
-- Maintainer: Jared Tobin <jared@ppad.tech>
--
-- What a contract's table says of an AArch64 encoding.

module Vestigia.Contract.Types (
    Operand(..)
  , Status(..)
  , Encoding(..)
  ) where

import qualified Data.Text as T
import Data.Word (Word32)

-- | A source register an encoding names, by the field it is read
--   from: a general-purpose register at 64 or 32 bits (field value
--   31 the zero register, or the stack pointer where the encoding
--   says so), a SIMD&FP register at a fixed width, a vector whose
--   width is the encoding's Q bit (bit 30), or a SIMD&FP register
--   read whole where nothing fixes its width.
data Operand =
    OpX
  | OpXSp
  | OpW
  | OpWSp
  | OpQ
  | OpD
  | OpS
  | OpH
  | OpB
  | OpV
  | OpVWhole
  deriving (Operand -> Operand -> Bool
(Operand -> Operand -> Bool)
-> (Operand -> Operand -> Bool) -> Eq Operand
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Operand -> Operand -> Bool
== :: Operand -> Operand -> Bool
$c/= :: Operand -> Operand -> Bool
/= :: Operand -> Operand -> Bool
Eq, Int -> Operand -> ShowS
[Operand] -> ShowS
Operand -> String
(Int -> Operand -> ShowS)
-> (Operand -> String) -> ([Operand] -> ShowS) -> Show Operand
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Operand -> ShowS
showsPrec :: Int -> Operand -> ShowS
$cshow :: Operand -> String
show :: Operand -> String
$cshowList :: [Operand] -> ShowS
showList :: [Operand] -> ShowS
Show)

-- | An encoding the contract covers; one it does not that is control
--   flow or system, which reads no data the contract speaks to; or one
--   it does not, with its source registers, each by the low bit of its
--   field.
data Status =
    Covered
  | Control
  | Outside ![(Int, Operand)]
  deriving (Status -> Status -> Bool
(Status -> Status -> Bool)
-> (Status -> Status -> Bool) -> Eq Status
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Status -> Status -> Bool
== :: Status -> Status -> Bool
$c/= :: Status -> Status -> Bool
/= :: Status -> Status -> Bool
Eq, Int -> Status -> ShowS
[Status] -> ShowS
Status -> String
(Int -> Status -> ShowS)
-> (Status -> String) -> ([Status] -> ShowS) -> Show Status
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Status -> ShowS
showsPrec :: Int -> Status -> ShowS
$cshow :: Status -> String
show :: Status -> String
$cshowList :: [Status] -> ShowS
showList :: [Status] -> ShowS
Show)

-- | An encoding, by its name in the specification, its fixed bits,
--   and what the contract says of it.
data Encoding = Encoding {
    Encoding -> Text
enName :: !T.Text
  , Encoding -> Word32
enMask :: !Word32
  , Encoding -> Word32
enValue :: !Word32
  , Encoding -> Status
enStatus :: !Status
  } deriving (Encoding -> Encoding -> Bool
(Encoding -> Encoding -> Bool)
-> (Encoding -> Encoding -> Bool) -> Eq Encoding
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Encoding -> Encoding -> Bool
== :: Encoding -> Encoding -> Bool
$c/= :: Encoding -> Encoding -> Bool
/= :: Encoding -> Encoding -> Bool
Eq, Int -> Encoding -> ShowS
[Encoding] -> ShowS
Encoding -> String
(Int -> Encoding -> ShowS)
-> (Encoding -> String) -> ([Encoding] -> ShowS) -> Show Encoding
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Encoding -> ShowS
showsPrec :: Int -> Encoding -> ShowS
$cshow :: Encoding -> String
show :: Encoding -> String
$cshowList :: [Encoding] -> ShowS
showList :: [Encoding] -> ShowS
Show)