{-# LANGUAGE FlexibleInstances     #-}
{-# LANGUAGE MultiParamTypeClasses #-}

module Asm.Ar ( Arch (..) ) where

import qualified Asm.Aarch64    as AArch64
import qualified Asm.Aarch64.B  as AArch64
import qualified Asm.Aarch64.CF as AArch64
import           Asm.BB
import qualified Asm.X86        as X86
import qualified Asm.X86.B      as X86
import qualified Asm.X86.CF     as X86
import           CF
import           Class.E

class Arch arch reg freg where
    cf :: [BB arch reg freg () ()] -> [BB arch reg freg () ControlAnn]

    -- | result: src, dest
    mI :: arch reg freg a -> Maybe (reg, reg)
    mf :: arch reg freg a -> Maybe (freg, freg)

    bb :: [arch reg freg a] -> [BB arch reg freg a ()]
    expand :: BB arch reg freg () Liveness -> [arch reg freg Liveness]
    udd :: arch reg freg a -> UD

instance (E reg, E freg) => Arch X86.X86 reg freg where
    cf :: [BB X86 reg freg () ()] -> [BB X86 reg freg () ControlAnn]
cf = [BB X86 reg freg () ()] -> [BB X86 reg freg () ControlAnn]
forall reg freg.
(E reg, E freg) =>
[BB X86 reg freg () ()] -> [BB X86 reg freg () ControlAnn]
X86.mkControlFlow

    mI :: forall a. X86 reg freg a -> Maybe (reg, reg)
mI (X86.MovRR a
_ reg
r0 reg
r1) = (reg, reg) -> Maybe (reg, reg)
forall a. a -> Maybe a
Just (reg
r1, reg
r0)
    mI X86 reg freg a
_                   = Maybe (reg, reg)
forall a. Maybe a
Nothing

    mf :: forall a. X86 reg freg a -> Maybe (freg, freg)
mf (X86.Movapd a
_ freg
r0 freg
r1) = (freg, freg) -> Maybe (freg, freg)
forall a. a -> Maybe a
Just (freg
r1, freg
r0)
    mf X86 reg freg a
_                    = Maybe (freg, freg)
forall a. Maybe a
Nothing

    bb :: forall a. [X86 reg freg a] -> [BB X86 reg freg a ()]
bb = [X86 reg freg a] -> [BB X86 reg freg a ()]
forall reg freg a. [X86 reg freg a] -> [BB X86 reg freg a ()]
X86.bb
    expand :: BB X86 reg freg () Liveness -> [X86 reg freg Liveness]
expand = BB X86 reg freg () Liveness -> [X86 reg freg Liveness]
forall reg freg.
(E reg, E freg) =>
BB X86 reg freg () Liveness -> [X86 reg freg Liveness]
X86.expand
    udd :: forall a. X86 reg freg a -> UD
udd = X86 reg freg a -> UD
forall {reg} {freg} {ann}.
(E reg, E freg) =>
X86 reg freg ann -> UD
X86.udd

instance (E reg, E freg) => Arch AArch64.AArch64 reg freg where
    cf :: [BB AArch64 reg freg () ()] -> [BB AArch64 reg freg () ControlAnn]
cf = [BB AArch64 reg freg () ()] -> [BB AArch64 reg freg () ControlAnn]
forall reg freg.
(E reg, E freg) =>
[BB AArch64 reg freg () ()] -> [BB AArch64 reg freg () ControlAnn]
AArch64.mkControlFlow

    mI :: forall a. AArch64 reg freg a -> Maybe (reg, reg)
mI (AArch64.MovRR a
_ reg
r0 reg
r1) = (reg, reg) -> Maybe (reg, reg)
forall a. a -> Maybe a
Just (reg
r0, reg
r1)
    mI AArch64 reg freg a
_                       = Maybe (reg, reg)
forall a. Maybe a
Nothing

    mf :: forall a. AArch64 reg freg a -> Maybe (freg, freg)
mf (AArch64.FMovXX a
_ freg
r0 freg
r1) = (freg, freg) -> Maybe (freg, freg)
forall a. a -> Maybe a
Just (freg
r0, freg
r1)
    mf AArch64 reg freg a
_                        = Maybe (freg, freg)
forall a. Maybe a
Nothing

    bb :: forall a. [AArch64 reg freg a] -> [BB AArch64 reg freg a ()]
bb = [AArch64 reg freg a] -> [BB AArch64 reg freg a ()]
forall reg freg a.
[AArch64 reg freg a] -> [BB AArch64 reg freg a ()]
AArch64.bb
    expand :: BB AArch64 reg freg () Liveness -> [AArch64 reg freg Liveness]
expand = BB AArch64 reg freg () Liveness -> [AArch64 reg freg Liveness]
forall reg freg.
(E reg, E freg) =>
BB AArch64 reg freg () Liveness -> [AArch64 reg freg Liveness]
AArch64.expand
    udd :: forall a. AArch64 reg freg a -> UD
udd = AArch64 reg freg a -> UD
forall {reg} {freg} {ann}.
(E reg, E freg) =>
AArch64 reg freg ann -> UD
AArch64.udd