module Asm.Aarch64.B ( bb ) where

import           Asm.Aarch64
import           Asm.BB
import           Data.List.Split (keepDelimsL, keepDelimsR, split, whenElt)

bb :: [AArch64 reg freg f2reg a] -> [BB AArch64 reg freg f2reg a ()]
bb :: forall reg freg f2reg a.
[AArch64 reg freg f2reg a] -> [BB AArch64 reg freg f2reg a ()]
bb = (BB AArch64 reg freg f2reg a () -> Bool)
-> [BB AArch64 reg freg f2reg a ()]
-> [BB AArch64 reg freg f2reg a ()]
forall a. (a -> Bool) -> [a] -> [a]
filter (Bool -> Bool
not(Bool -> Bool)
-> (BB AArch64 reg freg f2reg a () -> Bool)
-> BB AArch64 reg freg f2reg a ()
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
.BB AArch64 reg freg f2reg a () -> Bool
forall {arch :: * -> * -> * -> * -> *} {reg} {freg} {f2reg} {a}
       {b}.
BB arch reg freg f2reg a b -> Bool
emptyBB)([BB AArch64 reg freg f2reg a ()]
 -> [BB AArch64 reg freg f2reg a ()])
-> ([AArch64 reg freg f2reg a] -> [BB AArch64 reg freg f2reg a ()])
-> [AArch64 reg freg f2reg a]
-> [BB AArch64 reg freg f2reg a ()]
forall b c a. (b -> c) -> (a -> b) -> a -> c
.([AArch64 reg freg f2reg a] -> BB AArch64 reg freg f2reg a ())
-> [[AArch64 reg freg f2reg a]] -> [BB AArch64 reg freg f2reg a ()]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [AArch64 reg freg f2reg a] -> BB AArch64 reg freg f2reg a ()
forall {arch :: * -> * -> * -> * -> *} {reg} {freg} {f2reg} {a}.
[arch reg freg f2reg a] -> BB arch reg freg f2reg a ()
mkBB([[AArch64 reg freg f2reg a]] -> [BB AArch64 reg freg f2reg a ()])
-> ([AArch64 reg freg f2reg a] -> [[AArch64 reg freg f2reg a]])
-> [AArch64 reg freg f2reg a]
-> [BB AArch64 reg freg f2reg a ()]
forall b c a. (b -> c) -> (a -> b) -> a -> c
.([AArch64 reg freg f2reg a] -> [[AArch64 reg freg f2reg a]])
-> [[AArch64 reg freg f2reg a]] -> [[AArch64 reg freg f2reg a]]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (Splitter (AArch64 reg freg f2reg a)
-> [AArch64 reg freg f2reg a] -> [[AArch64 reg freg f2reg a]]
forall a. Splitter a -> [a] -> [[a]]
split (Splitter (AArch64 reg freg f2reg a)
-> Splitter (AArch64 reg freg f2reg a)
forall a. Splitter a -> Splitter a
keepDelimsL(Splitter (AArch64 reg freg f2reg a)
 -> Splitter (AArch64 reg freg f2reg a))
-> Splitter (AArch64 reg freg f2reg a)
-> Splitter (AArch64 reg freg f2reg a)
forall a b. (a -> b) -> a -> b
$(AArch64 reg freg f2reg a -> Bool)
-> Splitter (AArch64 reg freg f2reg a)
forall a. (a -> Bool) -> Splitter a
whenElt AArch64 reg freg f2reg a -> Bool
forall {reg} {freg} {f2} {a}. AArch64 reg freg f2 a -> Bool
isL))([[AArch64 reg freg f2reg a]] -> [[AArch64 reg freg f2reg a]])
-> ([AArch64 reg freg f2reg a] -> [[AArch64 reg freg f2reg a]])
-> [AArch64 reg freg f2reg a]
-> [[AArch64 reg freg f2reg a]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
.Splitter (AArch64 reg freg f2reg a)
-> [AArch64 reg freg f2reg a] -> [[AArch64 reg freg f2reg a]]
forall a. Splitter a -> [a] -> [[a]]
split (Splitter (AArch64 reg freg f2reg a)
-> Splitter (AArch64 reg freg f2reg a)
forall a. Splitter a -> Splitter a
keepDelimsR(Splitter (AArch64 reg freg f2reg a)
 -> Splitter (AArch64 reg freg f2reg a))
-> Splitter (AArch64 reg freg f2reg a)
-> Splitter (AArch64 reg freg f2reg a)
forall a b. (a -> b) -> a -> b
$(AArch64 reg freg f2reg a -> Bool)
-> Splitter (AArch64 reg freg f2reg a)
forall a. (a -> Bool) -> Splitter a
whenElt AArch64 reg freg f2reg a -> Bool
forall {reg} {freg} {f2} {a}. AArch64 reg freg f2 a -> Bool
cf)
    where cf :: AArch64 reg freg f2 a -> Bool
cf B{}=Bool
True; cf Bc{}=Bool
True; cf Cbnz{}=Bool
True; cf Tbnz{}=Bool
True; cf Tbz{}=Bool
True; cf C{}=Bool
True; cf RetL{}=Bool
True; cf AArch64 reg freg f2 a
_=Bool
False
          isL :: AArch64 reg freg f2 a -> Bool
isL Label{}=Bool
True; isL AArch64 reg freg f2 a
_=Bool
False
          mkBB :: [arch reg freg f2reg a] -> BB arch reg freg f2reg a ()
mkBB [arch reg freg f2reg a]
x = [arch reg freg f2reg a] -> () -> BB arch reg freg f2reg a ()
forall (arch :: * -> * -> * -> * -> *) reg freg f2reg a b.
[arch reg freg f2reg a] -> b -> BB arch reg freg f2reg a b
BB [arch reg freg f2reg a]
x ()
          emptyBB :: BB arch reg freg f2reg a b -> Bool
emptyBB (BB [] b
_)=Bool
True; emptyBB BB arch reg freg f2reg a b
_=Bool
False