{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
{-# OPTIONS_GHC -Wall -Werror #-}
module Documentation.SBV.Examples.BitPrecise.Legato where
import Data.Array (Array, Ix(..), (!), (//), array)
import Data.SBV
import Data.SBV.Tools.CodeGen
import GHC.Generics (Generic)
data Register = RegX | RegA deriving (Register -> Register -> Bool
(Register -> Register -> Bool)
-> (Register -> Register -> Bool) -> Eq Register
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Register -> Register -> Bool
== :: Register -> Register -> Bool
$c/= :: Register -> Register -> Bool
/= :: Register -> Register -> Bool
Eq, Eq Register
Eq Register =>
(Register -> Register -> Ordering)
-> (Register -> Register -> Bool)
-> (Register -> Register -> Bool)
-> (Register -> Register -> Bool)
-> (Register -> Register -> Bool)
-> (Register -> Register -> Register)
-> (Register -> Register -> Register)
-> Ord Register
Register -> Register -> Bool
Register -> Register -> Ordering
Register -> Register -> Register
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: Register -> Register -> Ordering
compare :: Register -> Register -> Ordering
$c< :: Register -> Register -> Bool
< :: Register -> Register -> Bool
$c<= :: Register -> Register -> Bool
<= :: Register -> Register -> Bool
$c> :: Register -> Register -> Bool
> :: Register -> Register -> Bool
$c>= :: Register -> Register -> Bool
>= :: Register -> Register -> Bool
$cmax :: Register -> Register -> Register
max :: Register -> Register -> Register
$cmin :: Register -> Register -> Register
min :: Register -> Register -> Register
Ord, Ord Register
Ord Register =>
((Register, Register) -> [Register])
-> ((Register, Register) -> Register -> Int)
-> ((Register, Register) -> Register -> Int)
-> ((Register, Register) -> Register -> Bool)
-> ((Register, Register) -> Int)
-> ((Register, Register) -> Int)
-> Ix Register
(Register, Register) -> Int
(Register, Register) -> [Register]
(Register, Register) -> Register -> Bool
(Register, Register) -> Register -> Int
forall a.
Ord a =>
((a, a) -> [a])
-> ((a, a) -> a -> Int)
-> ((a, a) -> a -> Int)
-> ((a, a) -> a -> Bool)
-> ((a, a) -> Int)
-> ((a, a) -> Int)
-> Ix a
$crange :: (Register, Register) -> [Register]
range :: (Register, Register) -> [Register]
$cindex :: (Register, Register) -> Register -> Int
index :: (Register, Register) -> Register -> Int
$cunsafeIndex :: (Register, Register) -> Register -> Int
unsafeIndex :: (Register, Register) -> Register -> Int
$cinRange :: (Register, Register) -> Register -> Bool
inRange :: (Register, Register) -> Register -> Bool
$crangeSize :: (Register, Register) -> Int
rangeSize :: (Register, Register) -> Int
$cunsafeRangeSize :: (Register, Register) -> Int
unsafeRangeSize :: (Register, Register) -> Int
Ix, Register
Register -> Register -> Bounded Register
forall a. a -> a -> Bounded a
$cminBound :: Register
minBound :: Register
$cmaxBound :: Register
maxBound :: Register
Bounded)
data Flag = FlagC | FlagZ deriving (Flag -> Flag -> Bool
(Flag -> Flag -> Bool) -> (Flag -> Flag -> Bool) -> Eq Flag
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Flag -> Flag -> Bool
== :: Flag -> Flag -> Bool
$c/= :: Flag -> Flag -> Bool
/= :: Flag -> Flag -> Bool
Eq, Eq Flag
Eq Flag =>
(Flag -> Flag -> Ordering)
-> (Flag -> Flag -> Bool)
-> (Flag -> Flag -> Bool)
-> (Flag -> Flag -> Bool)
-> (Flag -> Flag -> Bool)
-> (Flag -> Flag -> Flag)
-> (Flag -> Flag -> Flag)
-> Ord Flag
Flag -> Flag -> Bool
Flag -> Flag -> Ordering
Flag -> Flag -> Flag
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: Flag -> Flag -> Ordering
compare :: Flag -> Flag -> Ordering
$c< :: Flag -> Flag -> Bool
< :: Flag -> Flag -> Bool
$c<= :: Flag -> Flag -> Bool
<= :: Flag -> Flag -> Bool
$c> :: Flag -> Flag -> Bool
> :: Flag -> Flag -> Bool
$c>= :: Flag -> Flag -> Bool
>= :: Flag -> Flag -> Bool
$cmax :: Flag -> Flag -> Flag
max :: Flag -> Flag -> Flag
$cmin :: Flag -> Flag -> Flag
min :: Flag -> Flag -> Flag
Ord, Ord Flag
Ord Flag =>
((Flag, Flag) -> [Flag])
-> ((Flag, Flag) -> Flag -> Int)
-> ((Flag, Flag) -> Flag -> Int)
-> ((Flag, Flag) -> Flag -> Bool)
-> ((Flag, Flag) -> Int)
-> ((Flag, Flag) -> Int)
-> Ix Flag
(Flag, Flag) -> Int
(Flag, Flag) -> [Flag]
(Flag, Flag) -> Flag -> Bool
(Flag, Flag) -> Flag -> Int
forall a.
Ord a =>
((a, a) -> [a])
-> ((a, a) -> a -> Int)
-> ((a, a) -> a -> Int)
-> ((a, a) -> a -> Bool)
-> ((a, a) -> Int)
-> ((a, a) -> Int)
-> Ix a
$crange :: (Flag, Flag) -> [Flag]
range :: (Flag, Flag) -> [Flag]
$cindex :: (Flag, Flag) -> Flag -> Int
index :: (Flag, Flag) -> Flag -> Int
$cunsafeIndex :: (Flag, Flag) -> Flag -> Int
unsafeIndex :: (Flag, Flag) -> Flag -> Int
$cinRange :: (Flag, Flag) -> Flag -> Bool
inRange :: (Flag, Flag) -> Flag -> Bool
$crangeSize :: (Flag, Flag) -> Int
rangeSize :: (Flag, Flag) -> Int
$cunsafeRangeSize :: (Flag, Flag) -> Int
unsafeRangeSize :: (Flag, Flag) -> Int
Ix, Flag
Flag -> Flag -> Bounded Flag
forall a. a -> a -> Bounded a
$cminBound :: Flag
minBound :: Flag
$cmaxBound :: Flag
maxBound :: Flag
Bounded)
type Value = SWord 8
type Bit = SBool
type Registers = Array Register Value
type Flags = Array Flag Bit
data Location = F1
| F2
| LO
deriving (Location -> Location -> Bool
(Location -> Location -> Bool)
-> (Location -> Location -> Bool) -> Eq Location
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Location -> Location -> Bool
== :: Location -> Location -> Bool
$c/= :: Location -> Location -> Bool
/= :: Location -> Location -> Bool
Eq, Eq Location
Eq Location =>
(Location -> Location -> Ordering)
-> (Location -> Location -> Bool)
-> (Location -> Location -> Bool)
-> (Location -> Location -> Bool)
-> (Location -> Location -> Bool)
-> (Location -> Location -> Location)
-> (Location -> Location -> Location)
-> Ord Location
Location -> Location -> Bool
Location -> Location -> Ordering
Location -> Location -> Location
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: Location -> Location -> Ordering
compare :: Location -> Location -> Ordering
$c< :: Location -> Location -> Bool
< :: Location -> Location -> Bool
$c<= :: Location -> Location -> Bool
<= :: Location -> Location -> Bool
$c> :: Location -> Location -> Bool
> :: Location -> Location -> Bool
$c>= :: Location -> Location -> Bool
>= :: Location -> Location -> Bool
$cmax :: Location -> Location -> Location
max :: Location -> Location -> Location
$cmin :: Location -> Location -> Location
min :: Location -> Location -> Location
Ord, Ord Location
Ord Location =>
((Location, Location) -> [Location])
-> ((Location, Location) -> Location -> Int)
-> ((Location, Location) -> Location -> Int)
-> ((Location, Location) -> Location -> Bool)
-> ((Location, Location) -> Int)
-> ((Location, Location) -> Int)
-> Ix Location
(Location, Location) -> Int
(Location, Location) -> [Location]
(Location, Location) -> Location -> Bool
(Location, Location) -> Location -> Int
forall a.
Ord a =>
((a, a) -> [a])
-> ((a, a) -> a -> Int)
-> ((a, a) -> a -> Int)
-> ((a, a) -> a -> Bool)
-> ((a, a) -> Int)
-> ((a, a) -> Int)
-> Ix a
$crange :: (Location, Location) -> [Location]
range :: (Location, Location) -> [Location]
$cindex :: (Location, Location) -> Location -> Int
index :: (Location, Location) -> Location -> Int
$cunsafeIndex :: (Location, Location) -> Location -> Int
unsafeIndex :: (Location, Location) -> Location -> Int
$cinRange :: (Location, Location) -> Location -> Bool
inRange :: (Location, Location) -> Location -> Bool
$crangeSize :: (Location, Location) -> Int
rangeSize :: (Location, Location) -> Int
$cunsafeRangeSize :: (Location, Location) -> Int
unsafeRangeSize :: (Location, Location) -> Int
Ix, Location
Location -> Location -> Bounded Location
forall a. a -> a -> Bounded a
$cminBound :: Location
minBound :: Location
$cmaxBound :: Location
maxBound :: Location
Bounded)
type Memory = Array Location Value
data Mostek = Mostek { Mostek -> Memory
memory :: Memory
, Mostek -> Registers
registers :: Registers
, Mostek -> Flags
flags :: Flags
} deriving ((forall x. Mostek -> Rep Mostek x)
-> (forall x. Rep Mostek x -> Mostek) -> Generic Mostek
forall x. Rep Mostek x -> Mostek
forall x. Mostek -> Rep Mostek x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. Mostek -> Rep Mostek x
from :: forall x. Mostek -> Rep Mostek x
$cto :: forall x. Rep Mostek x -> Mostek
to :: forall x. Rep Mostek x -> Mostek
Generic, Bool -> SBool -> Mostek -> Mostek -> Mostek
(Bool -> SBool -> Mostek -> Mostek -> Mostek)
-> (forall b.
(Ord b, SymVal b, Num b, Num (SBV b)) =>
[Mostek] -> Mostek -> SBV b -> Mostek)
-> Mergeable Mostek
forall b.
(Ord b, SymVal b, Num b, Num (SBV b)) =>
[Mostek] -> Mostek -> SBV b -> Mostek
forall a.
(Bool -> SBool -> a -> a -> a)
-> (forall b.
(Ord b, SymVal b, Num b, Num (SBV b)) =>
[a] -> a -> SBV b -> a)
-> Mergeable a
$csymbolicMerge :: Bool -> SBool -> Mostek -> Mostek -> Mostek
symbolicMerge :: Bool -> SBool -> Mostek -> Mostek -> Mostek
$cselect :: forall b.
(Ord b, SymVal b, Num b, Num (SBV b)) =>
[Mostek] -> Mostek -> SBV b -> Mostek
select :: forall b.
(Ord b, SymVal b, Num b, Num (SBV b)) =>
[Mostek] -> Mostek -> SBV b -> Mostek
Mergeable)
type a = Mostek -> a
type Program = Mostek -> Mostek
getReg :: Register -> Extract Value
getReg :: Register -> Extract (SWord 8)
getReg Register
r Mostek
m = Mostek -> Registers
registers Mostek
m Registers -> Register -> SWord 8
forall i e. Ix i => Array i e -> i -> e
! Register
r
setReg :: Register -> Value -> Program
setReg :: Register -> SWord 8 -> Mostek -> Mostek
setReg Register
r SWord 8
v Mostek
m = Mostek
m {registers = registers m // [(r, v)]}
getFlag :: Flag -> Extract Bit
getFlag :: Flag -> Extract SBool
getFlag Flag
f Mostek
m = Mostek -> Flags
flags Mostek
m Flags -> Flag -> SBool
forall i e. Ix i => Array i e -> i -> e
! Flag
f
setFlag :: Flag -> Bit -> Program
setFlag :: Flag -> SBool -> Mostek -> Mostek
setFlag Flag
f SBool
b Mostek
m = Mostek
m {flags = flags m // [(f, b)]}
peek :: Location -> Extract Value
peek :: Location -> Extract (SWord 8)
peek Location
a Mostek
m = Mostek -> Memory
memory Mostek
m Memory -> Location -> SWord 8
forall i e. Ix i => Array i e -> i -> e
! Location
a
poke :: Location -> Value -> Program
poke :: Location -> SWord 8 -> Mostek -> Mostek
poke Location
a SWord 8
v Mostek
m = Mostek
m {memory = memory m // [(a, v)]}
checkOverflow :: SWord 8 -> SWord 8 -> SBool -> SBool
checkOverflow :: SWord 8 -> SWord 8 -> SBool -> SBool
checkOverflow SWord 8
x SWord 8
y SBool
c = SWord 8
s SWord 8 -> SWord 8 -> SBool
forall a. OrdSymbolic a => a -> a -> SBool
.< SWord 8
x SBool -> SBool -> SBool
.|| SWord 8
s SWord 8 -> SWord 8 -> SBool
forall a. OrdSymbolic a => a -> a -> SBool
.< SWord 8
y SBool -> SBool -> SBool
.|| SWord 8
s' SWord 8 -> SWord 8 -> SBool
forall a. OrdSymbolic a => a -> a -> SBool
.< SWord 8
s
where s :: SWord 8
s = SWord 8
x SWord 8 -> SWord 8 -> SWord 8
forall a. Num a => a -> a -> a
+ SWord 8
y
s' :: SWord 8
s' = SWord 8
s SWord 8 -> SWord 8 -> SWord 8
forall a. Num a => a -> a -> a
+ SBool -> SWord 8 -> SWord 8 -> SWord 8
forall a. Mergeable a => SBool -> a -> a -> a
ite SBool
c SWord 8
1 SWord 8
0
checkOverflowCorrect :: IO ThmResult
checkOverflowCorrect :: IO ThmResult
checkOverflowCorrect = SWord 8 -> SWord 8 -> SBool -> SBool
checkOverflow (SWord 8 -> SWord 8 -> SBool -> SBool)
-> (SWord 8 -> SWord 8 -> SBool -> SBool) -> IO ThmResult
forall a. Equality a => a -> a -> IO ThmResult
=== SWord 8 -> SWord 8 -> SBool -> SBool
overflow
where
overflow :: SWord 8 -> SWord 8 -> SBool -> SBool
overflow :: SWord 8 -> SWord 8 -> SBool -> SBool
overflow SWord 8
x SWord 8
y SBool
c = (SWord 8
0 SWord 8 -> SWord 8 -> SBV (WordN (8 + 8))
forall (n :: Nat) (bv :: Nat -> *) (m :: Nat).
(KnownNat n, BVIsNonZero n, SymVal (bv n), KnownNat m,
BVIsNonZero m, SymVal (bv m)) =>
SBV (bv n) -> SBV (bv m) -> SBV (bv (n + m))
# SWord 8
x) SWord 16 -> SWord 16 -> SWord 16
forall a. Num a => a -> a -> a
+ (SWord 8
0 SWord 8 -> SWord 8 -> SBV (WordN (8 + 8))
forall (n :: Nat) (bv :: Nat -> *) (m :: Nat).
(KnownNat n, BVIsNonZero n, SymVal (bv n), KnownNat m,
BVIsNonZero m, SymVal (bv m)) =>
SBV (bv n) -> SBV (bv m) -> SBV (bv (n + m))
# SWord 8
y) SWord 16 -> SWord 16 -> SWord 16
forall a. Num a => a -> a -> a
+ SBool -> SWord 16 -> SWord 16 -> SWord 16
forall a. Mergeable a => SBool -> a -> a -> a
ite SBool
c SWord 16
1 SWord 16
0 SWord 16 -> SWord 16 -> SBool
forall a. OrdSymbolic a => a -> a -> SBool
.> (SWord 16
255 :: SWord 16)
type Instruction = Program -> Program
ldx :: Value -> Instruction
ldx :: SWord 8 -> Instruction
ldx SWord 8
v Mostek -> Mostek
k = Mostek -> Mostek
k (Mostek -> Mostek) -> Instruction
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Register -> SWord 8 -> Mostek -> Mostek
setReg Register
RegX SWord 8
v
lda :: Value -> Instruction
lda :: SWord 8 -> Instruction
lda SWord 8
v Mostek -> Mostek
k = Mostek -> Mostek
k (Mostek -> Mostek) -> Instruction
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Register -> SWord 8 -> Mostek -> Mostek
setReg Register
RegA SWord 8
v
clc :: Instruction
clc :: Instruction
clc Mostek -> Mostek
k = Mostek -> Mostek
k (Mostek -> Mostek) -> Instruction
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Flag -> SBool -> Mostek -> Mostek
setFlag Flag
FlagC SBool
sFalse
rorM :: Location -> Instruction
rorM :: Location -> Instruction
rorM Location
a Mostek -> Mostek
k Mostek
m = Mostek -> Mostek
k (Mostek -> Mostek) -> Instruction
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Flag -> SBool -> Mostek -> Mostek
setFlag Flag
FlagC SBool
c' (Mostek -> Mostek) -> Instruction
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Location -> SWord 8 -> Mostek -> Mostek
poke Location
a SWord 8
v' Instruction
forall a b. (a -> b) -> a -> b
$ Mostek
m
where v :: SWord 8
v = Location -> Extract (SWord 8)
peek Location
a Mostek
m
c :: SBool
c = Flag -> Extract SBool
getFlag Flag
FlagC Mostek
m
v' :: SWord 8
v' = SWord 8 -> Int -> SBool -> SWord 8
forall a. SFiniteBits a => SBV a -> Int -> SBool -> SBV a
setBitTo (SWord 8
v SWord 8 -> Int -> SWord 8
forall a. Bits a => a -> Int -> a
`rotateR` Int
1) Int
7 SBool
c
c' :: SBool
c' = SWord 8 -> Int -> SBool
forall a. SFiniteBits a => SBV a -> Int -> SBool
sTestBit SWord 8
v Int
0
rorR :: Register -> Instruction
rorR :: Register -> Instruction
rorR Register
r Mostek -> Mostek
k Mostek
m = Mostek -> Mostek
k (Mostek -> Mostek) -> Instruction
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Flag -> SBool -> Mostek -> Mostek
setFlag Flag
FlagC SBool
c' (Mostek -> Mostek) -> Instruction
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Register -> SWord 8 -> Mostek -> Mostek
setReg Register
r SWord 8
v' Instruction
forall a b. (a -> b) -> a -> b
$ Mostek
m
where v :: SWord 8
v = Register -> Extract (SWord 8)
getReg Register
r Mostek
m
c :: SBool
c = Flag -> Extract SBool
getFlag Flag
FlagC Mostek
m
v' :: SWord 8
v' = SWord 8 -> Int -> SBool -> SWord 8
forall a. SFiniteBits a => SBV a -> Int -> SBool -> SBV a
setBitTo (SWord 8
v SWord 8 -> Int -> SWord 8
forall a. Bits a => a -> Int -> a
`rotateR` Int
1) Int
7 SBool
c
c' :: SBool
c' = SWord 8 -> Int -> SBool
forall a. SFiniteBits a => SBV a -> Int -> SBool
sTestBit SWord 8
v Int
0
bcc :: Program -> Instruction
bcc :: (Mostek -> Mostek) -> Instruction
bcc Mostek -> Mostek
l Mostek -> Mostek
k Mostek
m = SBool -> Mostek -> Mostek -> Mostek
forall a. Mergeable a => SBool -> a -> a -> a
ite (SBool
c SBool -> SBool -> SBool
forall a. EqSymbolic a => a -> a -> SBool
.== SBool
sFalse) (Mostek -> Mostek
l Mostek
m) (Mostek -> Mostek
k Mostek
m)
where c :: SBool
c = Flag -> Extract SBool
getFlag Flag
FlagC Mostek
m
adc :: Location -> Instruction
adc :: Location -> Instruction
adc Location
a Mostek -> Mostek
k Mostek
m = Mostek -> Mostek
k (Mostek -> Mostek) -> Instruction
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Flag -> SBool -> Mostek -> Mostek
setFlag Flag
FlagZ (SWord 8
v' SWord 8 -> SWord 8 -> SBool
forall a. EqSymbolic a => a -> a -> SBool
.== SWord 8
0) (Mostek -> Mostek) -> Instruction
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Flag -> SBool -> Mostek -> Mostek
setFlag Flag
FlagC SBool
c' (Mostek -> Mostek) -> Instruction
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Register -> SWord 8 -> Mostek -> Mostek
setReg Register
RegA SWord 8
v' Instruction
forall a b. (a -> b) -> a -> b
$ Mostek
m
where v :: SWord 8
v = Location -> Extract (SWord 8)
peek Location
a Mostek
m
ra :: SWord 8
ra = Register -> Extract (SWord 8)
getReg Register
RegA Mostek
m
c :: SBool
c = Flag -> Extract SBool
getFlag Flag
FlagC Mostek
m
v' :: SWord 8
v' = SWord 8
v SWord 8 -> SWord 8 -> SWord 8
forall a. Num a => a -> a -> a
+ SWord 8
ra SWord 8 -> SWord 8 -> SWord 8
forall a. Num a => a -> a -> a
+ SBool -> SWord 8 -> SWord 8 -> SWord 8
forall a. Mergeable a => SBool -> a -> a -> a
ite SBool
c SWord 8
1 SWord 8
0
c' :: SBool
c' = SWord 8 -> SWord 8 -> SBool -> SBool
checkOverflow SWord 8
v SWord 8
ra SBool
c
dex :: Instruction
dex :: Instruction
dex Mostek -> Mostek
k Mostek
m = Mostek -> Mostek
k (Mostek -> Mostek) -> Instruction
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Flag -> SBool -> Mostek -> Mostek
setFlag Flag
FlagZ (SWord 8
x SWord 8 -> SWord 8 -> SBool
forall a. EqSymbolic a => a -> a -> SBool
.== SWord 8
0) (Mostek -> Mostek) -> Instruction
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Register -> SWord 8 -> Mostek -> Mostek
setReg Register
RegX SWord 8
x Instruction
forall a b. (a -> b) -> a -> b
$ Mostek
m
where x :: SWord 8
x = Register -> Extract (SWord 8)
getReg Register
RegX Mostek
m SWord 8 -> SWord 8 -> SWord 8
forall a. Num a => a -> a -> a
- SWord 8
1
bne :: Program -> Instruction
bne :: (Mostek -> Mostek) -> Instruction
bne Mostek -> Mostek
l Mostek -> Mostek
k Mostek
m = SBool -> Mostek -> Mostek -> Mostek
forall a. Mergeable a => SBool -> a -> a -> a
ite (SBool
z SBool -> SBool -> SBool
forall a. EqSymbolic a => a -> a -> SBool
.== SBool
sFalse) (Mostek -> Mostek
l Mostek
m) (Mostek -> Mostek
k Mostek
m)
where z :: SBool
z = Flag -> Extract SBool
getFlag Flag
FlagZ Mostek
m
end :: Program
end :: Mostek -> Mostek
end = Mostek -> Mostek
forall a. a -> a
id
legato :: Program
legato :: Mostek -> Mostek
legato = Mostek -> Mostek
start
where start :: Mostek -> Mostek
start = SWord 8 -> Instruction
ldx SWord 8
8
Instruction -> Instruction
forall a b. (a -> b) -> a -> b
$ SWord 8 -> Instruction
lda SWord 8
0
Instruction -> Instruction
forall a b. (a -> b) -> a -> b
$ Mostek -> Mostek
loop
loop :: Mostek -> Mostek
loop = Location -> Instruction
rorM Location
F1
Instruction -> Instruction
forall a b. (a -> b) -> a -> b
$ (Mostek -> Mostek) -> Instruction
bcc Mostek -> Mostek
zeroCoef
Instruction -> Instruction
forall a b. (a -> b) -> a -> b
$ Instruction
clc
Instruction -> Instruction
forall a b. (a -> b) -> a -> b
$ Location -> Instruction
adc Location
F2
Instruction -> Instruction
forall a b. (a -> b) -> a -> b
$ Mostek -> Mostek
zeroCoef
zeroCoef :: Mostek -> Mostek
zeroCoef = Register -> Instruction
rorR Register
RegA
Instruction -> Instruction
forall a b. (a -> b) -> a -> b
$ Location -> Instruction
rorM Location
LO
Instruction -> Instruction
forall a b. (a -> b) -> a -> b
$ Instruction
dex
Instruction -> Instruction
forall a b. (a -> b) -> a -> b
$ (Mostek -> Mostek) -> Instruction
bne Mostek -> Mostek
loop
Instruction -> Instruction
forall a b. (a -> b) -> a -> b
$ Mostek -> Mostek
end
runLegato :: Mostek -> (Value, Value)
runLegato :: Mostek -> (SWord 8, SWord 8)
runLegato Mostek
m = (Register -> Extract (SWord 8)
getReg Register
RegA Mostek
m', Location -> Extract (SWord 8)
peek Location
LO Mostek
m')
where m' :: Mostek
m' = Mostek -> Mostek
legato Mostek
m
type InitVals = ( Value
, Value
, Value
, Value
, Value
, Bit
, Bit
)
initMachine :: InitVals -> Mostek
initMachine :: InitVals -> Mostek
initMachine (SWord 8
f1, SWord 8
f2, SWord 8
lo, SWord 8
rx, SWord 8
ra, SBool
fc, SBool
fz) = Mostek { memory :: Memory
memory = (Location, Location) -> [(Location, SWord 8)] -> Memory
forall i e. Ix i => (i, i) -> [(i, e)] -> Array i e
array (Location
forall a. Bounded a => a
minBound, Location
forall a. Bounded a => a
maxBound) [(Location
F1, SWord 8
f1), (Location
F2, SWord 8
f2), (Location
LO, SWord 8
lo)]
, registers :: Registers
registers = (Register, Register) -> [(Register, SWord 8)] -> Registers
forall i e. Ix i => (i, i) -> [(i, e)] -> Array i e
array (Register
forall a. Bounded a => a
minBound, Register
forall a. Bounded a => a
maxBound) [(Register
RegX, SWord 8
rx), (Register
RegA, SWord 8
ra)]
, flags :: Flags
flags = (Flag, Flag) -> [(Flag, SBool)] -> Flags
forall i e. Ix i => (i, i) -> [(i, e)] -> Array i e
array (Flag
forall a. Bounded a => a
minBound, Flag
forall a. Bounded a => a
maxBound) [(Flag
FlagC, SBool
fc), (Flag
FlagZ, SBool
fz)]
}
legatoIsCorrect :: InitVals -> SBool
legatoIsCorrect :: InitVals -> SBool
legatoIsCorrect initVals :: InitVals
initVals@(SWord 8
x, SWord 8
y, SWord 8
_, SWord 8
_, SWord 8
_, SBool
_, SBool
_) = SWord 16
result SWord 16 -> SWord 16 -> SBool
forall a. EqSymbolic a => a -> a -> SBool
.== SWord 16
expected
where (SWord 8
hi, SWord 8
lo) = Mostek -> (SWord 8, SWord 8)
runLegato (InitVals -> Mostek
initMachine InitVals
initVals)
result, expected :: SWord 16
result :: SWord 16
result = SWord 16
256 SWord 16 -> SWord 16 -> SWord 16
forall a. Num a => a -> a -> a
* (SWord 8
0 SWord 8 -> SWord 8 -> SBV (WordN (8 + 8))
forall (n :: Nat) (bv :: Nat -> *) (m :: Nat).
(KnownNat n, BVIsNonZero n, SymVal (bv n), KnownNat m,
BVIsNonZero m, SymVal (bv m)) =>
SBV (bv n) -> SBV (bv m) -> SBV (bv (n + m))
# SWord 8
hi) SWord 16 -> SWord 16 -> SWord 16
forall a. Num a => a -> a -> a
+ (SWord 8
0 SWord 8 -> SWord 8 -> SBV (WordN (8 + 8))
forall (n :: Nat) (bv :: Nat -> *) (m :: Nat).
(KnownNat n, BVIsNonZero n, SymVal (bv n), KnownNat m,
BVIsNonZero m, SymVal (bv m)) =>
SBV (bv n) -> SBV (bv m) -> SBV (bv (n + m))
# SWord 8
lo)
expected :: SWord 16
expected = (SWord 8
0 SWord 8 -> SWord 8 -> SBV (WordN (8 + 8))
forall (n :: Nat) (bv :: Nat -> *) (m :: Nat).
(KnownNat n, BVIsNonZero n, SymVal (bv n), KnownNat m,
BVIsNonZero m, SymVal (bv m)) =>
SBV (bv n) -> SBV (bv m) -> SBV (bv (n + m))
# SWord 8
x) SWord 16 -> SWord 16 -> SWord 16
forall a. Num a => a -> a -> a
* (SWord 8
0 SWord 8 -> SWord 8 -> SBV (WordN (8 + 8))
forall (n :: Nat) (bv :: Nat -> *) (m :: Nat).
(KnownNat n, BVIsNonZero n, SymVal (bv n), KnownNat m,
BVIsNonZero m, SymVal (bv m)) =>
SBV (bv n) -> SBV (bv m) -> SBV (bv (n + m))
# SWord 8
y)
correctnessTheorem :: IO ThmResult
correctnessTheorem :: IO ThmResult
correctnessTheorem = SMTConfig -> SymbolicT IO SBool -> IO ThmResult
forall a. Provable a => SMTConfig -> a -> IO ThmResult
proveWith SMTConfig
defaultSMTCfg{timing = PrintTiming} (SymbolicT IO SBool -> IO ThmResult)
-> SymbolicT IO SBool -> IO ThmResult
forall a b. (a -> b) -> a -> b
$ do
lo <- String -> Symbolic (SWord 8)
forall (n :: Nat).
(KnownNat n, BVIsNonZero n) =>
String -> Symbolic (SWord n)
sWord String
"lo"
x <- sWord "x"
y <- sWord "y"
regX <- sWord "regX"
regA <- sWord "regA"
flagC <- sBool "flagC"
flagZ <- sBool "flagZ"
return $ legatoIsCorrect (x, y, lo, regX, regA, flagC, flagZ)
legatoInC :: IO ()
legatoInC :: IO ()
legatoInC = Maybe String -> String -> SBVCodeGen () -> IO ()
forall a. Maybe String -> String -> SBVCodeGen a -> IO a
compileToC Maybe String
forall a. Maybe a
Nothing String
"runLegato" (SBVCodeGen () -> IO ()) -> SBVCodeGen () -> IO ()
forall a b. (a -> b) -> a -> b
$ do
x <- String -> SBVCodeGen (SWord 8)
forall a. SymVal a => String -> SBVCodeGen (SBV a)
cgInput String
"x"
y <- cgInput "y"
let (hi, lo) = runLegato (initMachine (x, y, 0, 0, 0, sFalse, sFalse))
cgOutput "hi" hi
cgOutput "lo" lo