packages feed

harpy 0.2 → 0.4

raw patch · 16 files changed

+5299/−3496 lines, 16 filesdep +arraydep +containersdep +prettydep ~base

Dependencies added: array, containers, pretty

Dependency ranges changed: base

Files

+ Harpy.hs view
@@ -0,0 +1,22 @@+--------------------------------------------------------------------------+-- |+-- Module:      Harpy+-- Copyright:   (c) 2006-2007 Martin Grabmueller and Dirk Kleeblatt+-- License:     GPL+-- +-- Maintainer:  {magr,klee}@cs.tu-berlin.de+-- Stability:   provisional+-- Portability: portable+--+-- Harpy is a library for run-time code generation of x86 machine code.+--+-- This is a convenience module which re-exports the modules which are+-- essential for using Harpy.+----------------------------------------------------------------------------+module Harpy(module Harpy.CodeGenMonad,+             module Harpy.Call,+             module Harpy.X86Assembler) where++import Harpy.CodeGenMonad+import Harpy.Call+import Harpy.X86Assembler
Harpy/Call.hs view
@@ -2,7 +2,7 @@  -------------------------------------------------------------------------- -- |--- Module      :  Call+-- Module      :  Harpy.Call -- Copyright   :  (c) 2006-2007 Martin Grabmueller and Dirk Kleeblatt -- License     :  GPL -- 
Harpy/CodeGenMonad.hs view
@@ -2,13 +2,13 @@  -------------------------------------------------------------------------- -- |--- Module      :  CodeGenMonad--- Copyright   :  (c) 2006-2007 Martin Grabmueller and Dirk Kleeblatt--- License     :  GPL+-- Module:      Harpy.CodeGenMonad+-- Copyright:   (c) 2006-2007 Martin Grabmueller and Dirk Kleeblatt+-- License:     GPL -- --- Maintainer  :  {magr,klee}@cs.tu-berlin.de--- Stability   :  provisional--- Portability :  portable (but generated code non-portable)+-- Maintainer:  {magr,klee}@cs.tu-berlin.de+-- Stability:   provisional+-- Portability: portable (but generated code non-portable) -- -- Monad for generating x86 machine code at runtime. --@@ -16,20 +16,21 @@ -- the details of handling code buffers, emitting binary data, -- relocation etc. ----- All the code generation functions in module "Harpy.X86CodeGen"--- live in this monad and use its error reporting facilities as well--- as the internal state maintained by the monad.  The user state is--- independent from the internal state and may be used by--- higher-level code generation libraries to maintain their own--- state across code generation operations.+-- All the code generation functions in module "Harpy.X86CodeGen" live+-- in this monad and use its error reporting facilities as well as the+-- internal state maintained by the monad.   -----------------------------------------------------------------------------+-- The library user can pass a user environment and user state through+-- the monad.  This state is independent from the internal state and+-- may be used by higher-level code generation libraries to maintain+-- their own state across code generation operations.+-- --------------------------------------------------------------------------  module Harpy.CodeGenMonad(     -- * Types           CodeGen,-          RelocKind(..),           ErrMsg,+          RelocKind(..),           Reloc,           Label,           FixupKind(..),@@ -50,6 +51,7 @@           withEnv,     -- ** Label management           newLabel,+          newNamedLabel,           setLabel,           defineLabel,           (@@),@@ -78,12 +80,12 @@ import Control.Monad  import Text.PrettyPrint.HughesPJ-import Text.Printf -import Data.Word+import Numeric++import Data.List import qualified Data.Map as Map import Foreign-import System.Cmd import System.IO  import Control.Monad.Trans@@ -98,37 +100,53 @@ -- monad. newtype CodeGen e s a = CodeGen ((e, CodeGenEnv) -> (s, CodeGenState) -> IO ((s, CodeGenState), Either ErrMsg a)) --- | Configuration of the code generator.-data CodeGenConfig = CodeGenConfig { codeBufferSize :: Int -- ^ Size of individual code buffer blocks. -                                     }+-- | Configuration of the code generator.  There are currently two+-- configuration options.  The first is the number fo bytes to use for+-- allocating code buffers (the first as well as additional buffers+-- created in calls to 'ensureBufferSize'.  The second allows to pass+-- in a pre-allocated code buffer and its size.  When this option is+-- used, Harpy does not perform any code buffer resizing (calls to+-- 'ensureBufferSize' will be equivalent to calls to+-- 'checkBufferSize').+data CodeGenConfig = CodeGenConfig { +      codeBufferSize   :: Int,                   -- ^ Size of individual code buffer blocks. +      customCodeBuffer :: Maybe (Ptr Word8, Int) -- ^ Code buffer passed in.+    }  -- | Internal state of the code generator-data CodeGenState = CodeGenState { buffer :: Ptr Word8,-                                   bufferList :: [(Ptr Word8, Int)],-                                   firstBuffer :: Ptr Word8,-                                   bufferOfs :: Int,-                                   bufferSize :: Int,-                                   relocEntries :: [Reloc],-                                   nextLabel :: Int,-                                   definedLabels :: Map.Map Int (Ptr Word8, Int),-                                   pendingFixups :: Map.Map Int [FixupEntry],-                                   config :: CodeGenConfig}+data CodeGenState = CodeGenState { +      buffer        :: Ptr Word8,                    -- ^ Pointer to current code buffer.+      bufferList    :: [(Ptr Word8, Int)],           -- ^ List of all other code buffers.+      firstBuffer   :: Ptr Word8,                    -- ^ Pointer to first buffer.+      bufferOfs     :: Int,                          -- ^ Current offset into buffer where next instruction will be stored.+      bufferSize    :: Int,                          -- ^ Size of current buffer.+      relocEntries  :: [Reloc],                      -- ^ List of all emitted relocation entries.+      nextLabel     :: Int,                          -- ^ Counter for generating labels.+      definedLabels :: Map.Map Int (Ptr Word8, Int, String), -- ^ Map of already defined labels.+      pendingFixups :: Map.Map Int [FixupEntry],     -- ^ Map of labels which have been referenced, but not defined.+      config        :: CodeGenConfig                 -- ^ Configuration record.+    } -data FixupKind = Fixup8-               | Fixup16-               | Fixup32-               | Fixup32Absolute-               deriving (Show)+data FixupEntry = FixupEntry { +      fueBuffer :: Ptr Word8,+      fueOfs    :: Int,+      fueKind   :: FixupKind +    } -data FixupEntry = FixupEntry { fueBuffer :: Ptr Word8,-                               fueOfs :: Int,-                               fueKind :: FixupKind }+-- | Kind of a fixup entry.  When a label is emitted with+-- 'defineLabel', all prior references to this label must be fixed+-- up.  This data type tells how to perform the fixup operation.+data FixupKind = Fixup8          -- ^ 8-bit relative reference+               | Fixup16         -- ^ 16-bit relative reference+               | Fixup32         -- ^ 32-bit relative reference+               | Fixup32Absolute -- ^ 32-bit absolute reference+               deriving (Show)  data CodeGenEnv = CodeGenEnv { tailContext :: Bool }    deriving (Show)  -- | Kind of relocation, for example PC-relative-data RelocKind = RelocPCRel -- ^ PC-relative relocation+data RelocKind = RelocPCRel    -- ^ PC-relative relocation                | RelocAbsolute -- ^ Absolute address    deriving (Show) @@ -143,7 +161,7 @@    deriving (Show)  -- | Label-data Label = Label Int+data Label = Label Int String  unCg :: CodeGen e s a -> ((e, CodeGenEnv) -> (s, CodeGenState) -> IO ((s, CodeGenState), Either ErrMsg a)) unCg (CodeGen a) = a@@ -153,11 +171,13 @@     fail err = cgFail err     m >>= k = cgBind m k --- {-# INLINE cgReturn #-}+cgReturn :: a -> CodeGen e s a cgReturn x = CodeGen (\_env state -> return (state, Right x))--- {-# INLINE cgFail #-}++cgFail :: String -> CodeGen e s a cgFail err = CodeGen (\_env state -> return (state, Left (text err)))--- {-# INLINE cgBind #-}++cgBind :: CodeGen e s a -> (a -> CodeGen e s a1) -> CodeGen e s a1 cgBind m k = CodeGen (\env state ->                 do r1 <- unCg m env state                   case r1 of@@ -183,29 +203,44 @@                                    pendingFixups = Map.empty,                                    config = defaultCodeGenConfig} +-- | Default code generation configuration.  The code buffer size is+-- set to 4KB, and code buffer management is automatic.  This value is+-- intended to be used with record update syntax, for example:+--+-- >  runCodeGenWithConfig ... defaultCodeGenConfig{codeBufferSize = 128} ... defaultCodeGenConfig :: CodeGenConfig-defaultCodeGenConfig = CodeGenConfig { codeBufferSize = defaultCodeBufferSize }+defaultCodeGenConfig = CodeGenConfig { codeBufferSize = defaultCodeBufferSize,+                                       customCodeBuffer = Nothing }  defaultCodeBufferSize :: Int-defaultCodeBufferSize = 128+defaultCodeBufferSize = 4096 --- | Execute code generation, given a user environment and state.--- The result is a tuple of the resulting user state and either an--- error message (when code generation failed) or the result of the--- code generation.+-- | Execute code generation, given a user environment and state.  The+-- result is a tuple of the resulting user state and either an error+-- message (when code generation failed) or the result of the code+-- generation.  This function runs 'runCodeGenWithConfig' with a+-- sensible default configuration. runCodeGen :: CodeGen e s a -> e -> s -> IO (s, Either ErrMsg a) runCodeGen cg uenv ustate =     runCodeGenWithConfig cg uenv ustate defaultCodeGenConfig +-- | Like 'runCodeGen', but allows more control over the code+-- generation process.  In addition to a code generator and a user+-- environment and state, a code generation configuration must be+-- provided.  A code generation configuration allows control over the+-- allocation of code buffers, for example. runCodeGenWithConfig :: CodeGen e s a -> e -> s -> CodeGenConfig -> IO (s, Either ErrMsg a) runCodeGenWithConfig (CodeGen cg) uenv ustate conf =-    do let initSize = codeBufferSize conf-       arr <- mallocBytes initSize+    do (buf, sze) <- case customCodeBuffer conf of+                       Nothing -> do let initSize = codeBufferSize conf+                                     arr <- mallocBytes initSize+                                     return (arr, initSize)+                       Just (buf, sze) -> return (buf, sze)        let env = CodeGenEnv {tailContext = True}-       let state = emptyCodeGenState{buffer = arr,+       let state = emptyCodeGenState{buffer = buf,                                      bufferList = [],-                                     firstBuffer = arr,-                                     bufferSize = initSize,+                                     firstBuffer = buf,+                                     bufferSize = sze,                                      config = conf}        ((ustate', _), res) <- cg (uenv, env) (ustate, state)        return (ustate', res)@@ -215,6 +250,9 @@ -- whenever it cannot be guaranteed that the code buffer is large -- enough to hold all the generated code.  Lets the code generation -- monad fail when the buffer overflows.+--+-- /Note:/ Starting with version 0.4, Harpy automatically checks for+-- buffer overflow, so you do not need to call this function anymore. checkBufferSize :: Int -> CodeGen e s () checkBufferSize needed =     do state <- getInternalState@@ -226,57 +264,63 @@                             int (bufferSize state) <> text ")"))  -- | Make sure that the code buffer has room for at least the given--- number of bytes.  This should be called by code generators--- whenever it cannot be guaranteed that the code buffer is large--- enough to hold all the generated code.  Creates a new buffer and--- places a jump to the new buffer when there is not sufficient space--- available+-- number of bytes.  This should be called by code generators whenever+-- it cannot be guaranteed that the code buffer is large enough to+-- hold all the generated code.  Creates a new buffer and places a+-- jump to the new buffer when there is not sufficient space+-- available.  When code generation was invoked with a pre-defined+-- code buffer, code generation is aborted on overflow.+--+-- /Note:/ Starting with version 0.4, Harpy automatically checks for+-- buffer overflow, so you do not need to call this function anymore. ensureBufferSize :: Int -> CodeGen e s () ensureBufferSize needed =     do state <- getInternalState-       unless (bufferOfs state + needed + 5 <= bufferSize state)-              (do let incrSize = max (needed + 16) -                                     (codeBufferSize (config state))-                  arr <- liftIO $ mallocBytes incrSize-                  ofs <- getCodeOffset-                  let buf = buffer state-                      disp :: Int-                      disp = arr `minusPtr` (buf `plusPtr` ofs) - 5-                  emit8 0xe9-                  emit32 (fromIntegral disp)-                  st <- getInternalState-                  setInternalState st{buffer = arr, bufferList = bufferList st ++ [(buffer st, bufferOfs st)], bufferOfs = 0})+       case (customCodeBuffer (config state)) of+         Nothing ->+             unless (bufferOfs state + needed + 5 <= bufferSize state)+                        (do let incrSize = max (needed + 16) (codeBufferSize (config state))+                            arr <- liftIO $ mallocBytes incrSize+                            ofs <- getCodeOffset+                            let buf = buffer state+                                disp :: Int+                                disp = arr `minusPtr` (buf `plusPtr` ofs) - 5+                            emit8 0xe9    -- FIXME: Machine dependent!+                            emit32 (fromIntegral disp)+                            st <- getInternalState+                            setInternalState st{buffer = arr, bufferList = bufferList st ++ [(buffer st, bufferOfs st)], bufferOfs = 0})+         Just (_, _) -> checkBufferSize needed  -- | Return a pointer to the beginning of the first code buffer, which -- is normally the entry point to the generated code. getEntryPoint :: CodeGen e s (Ptr Word8) getEntryPoint =-    CodeGen (\ env (ustate, state) -> +    CodeGen (\ _ (ustate, state) ->        return $ ((ustate, state), Right (firstBuffer state)))  -- | Return the current offset in the code buffer, e.g. the offset -- at which the next instruction will be emitted. getCodeOffset :: CodeGen e s Int getCodeOffset =-    CodeGen (\ env (ustate, state) -> +    CodeGen (\ _ (ustate, state) ->        return $ ((ustate, state), Right (bufferOfs state)))  -- | Set the user state to the given value.  setState :: s -> CodeGen e s () setState st =-    CodeGen (\ env (_, state) -> +    CodeGen (\ _ (_, state) ->        return $ ((st, state), Right ()))  -- | Return the current user state. getState :: CodeGen e s s getState =-    CodeGen (\ env (ustate, state) -> +    CodeGen (\ _ (ustate, state) ->        return $ ((ustate, state), Right (ustate)))  -- | Return the current user environment. getEnv :: CodeGen e s e getEnv =-    CodeGen (\ (uenv, env) state -> +    CodeGen (\ (uenv, _) state ->        return $ (state, Right uenv))  -- | Set the environment to the given value and execute the given@@ -289,20 +333,19 @@ -- | Set the user state to the given value.  setInternalState :: CodeGenState -> CodeGen e s () setInternalState st =-    CodeGen (\ env (ustate, _) -> +    CodeGen (\ _ (ustate, _) ->        return $ ((ustate, st), Right ()))  -- | Return the current user state. getInternalState :: CodeGen e s CodeGenState getInternalState =-    CodeGen (\ env (ustate, state) -> +    CodeGen (\ _ (ustate, state) ->        return $ ((ustate, state), Right (state)))  -- | Return the pointer to the start of the code buffer.--- {-# INLINE getBasePtr #-} getBasePtr :: CodeGen e s (Ptr Word8) getBasePtr =-    CodeGen (\ env (ustate, state) -> +    CodeGen (\ _ (ustate, state) ->        return $ ((ustate, state), Right (buffer state)))  -- | Return a list of all code buffers and their respective size @@ -312,14 +355,24 @@                        return $ bufferList st ++ [(buffer st, bufferOfs st)]  -- | Generate a new label to be used with the label operations--- 'emitRelocInfo', 'emitFixup' and 'defineLabel'.+-- 'emitFixup' and 'defineLabel'. newLabel :: CodeGen e s Label newLabel =     do state <- getInternalState        let lab = nextLabel state        setInternalState state{nextLabel = lab + 1}-       return (Label lab)+       return (Label lab "") +-- | Generate a new label to be used with the label operations+-- 'emitFixup' and 'defineLabel'.  The given name is used for+-- diagnostic purposes, and will appear in the disassembly.+newNamedLabel :: String -> CodeGen e s Label+newNamedLabel name =+    do state <- getInternalState+       let lab = nextLabel state+       setInternalState state{nextLabel = lab + 1}+       return (Label lab name)+ -- | Generate a new label and define it at once setLabel :: CodeGen e s Label setLabel =@@ -330,58 +383,52 @@ -- | Emit a relocation entry for the given offset, relocation kind  -- and target address. emitRelocInfo :: Int -> RelocKind -> FunPtr a -> CodeGen e s ()-emitRelocInfo ofs kind addr = -    CodeGen (\ env (ustate, state) -> -      do let newState = state{relocEntries =+emitRelocInfo ofs knd addr = +    do state <- getInternalState+       setInternalState state{relocEntries =                               Reloc{offset = ofs, -                                    kind = kind,+                                    kind = knd,                                     address = castFunPtr addr} :                                (relocEntries state)}-         return $ ((ustate, newState), Right ()))  -- | Emit a byte value to the code buffer. --- {-# INLINE emit8 #-} emit8 :: Word8 -> CodeGen e s () emit8 op = -    CodeGen (\ env (ustate, state) -> +    CodeGen (\ _ (ustate, state) ->        do let buf = buffer state              ptr = bufferOfs state          pokeByteOff buf ptr op          return $ ((ustate, state{bufferOfs = ptr + 1}), Right ()))  -- | Store a byte value at the given offset into the code buffer.--- {-# INLINE emit8At #-} emit8At :: Int -> Word8 -> CodeGen e s () emit8At pos op = -    CodeGen (\ env (ustate, state) -> +    CodeGen (\ _ (ustate, state) ->        do let buf = buffer state          pokeByteOff buf pos op          return $ ((ustate, state), Right ()))  -- | Return the byte value at the given offset in the code buffer.--- {-# INLINE peek8At #-} peek8At :: Int -> CodeGen e s Word8 peek8At pos =-    CodeGen (\ env (ustate, state) -> +    CodeGen (\ _ (ustate, state) ->        do let buf = buffer state          b <- peekByteOff buf pos          return $ ((ustate, state), Right b))  -- | Like 'emit8', but for a 32-bit value.--- {-# INLINE emit32 #-} emit32 :: Word32 -> CodeGen e s () emit32 op = -    CodeGen (\ env (ustate, state) -> +    CodeGen (\ _ (ustate, state) ->        do let buf = buffer state              ptr = bufferOfs state          pokeByteOff buf ptr op          return $ ((ustate, state{bufferOfs = ptr + 4}), Right ()))  -- | Like 'emit8At', but for a 32-bit value.--- {-# INLINE emit32At #-} emit32At :: Int -> Word32 -> CodeGen e s () emit32At pos op = -    CodeGen (\ env (ustate, state) -> +    CodeGen (\ _ (ustate, state) ->        do let buf = buffer state          pokeByteOff buf pos op          return $ ((ustate, state), Right ()))@@ -389,19 +436,23 @@ -- | Emit a label at the current offset in the code buffer.  All -- references to the label will be relocated to this offset. defineLabel :: Label -> CodeGen e s ()-defineLabel (Label lab) = +defineLabel (Label lab name) =      do state <- getInternalState+       case Map.lookup lab (definedLabels state) of+         Just _ -> failCodeGen $ text "duplicate definition of label" <+> +                     int lab+         _ -> return ()        case Map.lookup lab (pendingFixups state) of          Just fixups -> do mapM_ (performFixup (buffer state) (bufferOfs state)) fixups                            setInternalState state{pendingFixups = Map.delete lab (pendingFixups state)}          Nothing -> return ()-       state <- getInternalState-       setInternalState state{definedLabels = Map.insert lab (buffer state, bufferOfs state) (definedLabels state)}+       state1 <- getInternalState+       setInternalState state1{definedLabels = Map.insert lab (buffer state1, bufferOfs state1, name) (definedLabels state1)}  performFixup :: Ptr Word8 -> Int -> FixupEntry -> CodeGen e s ()-performFixup labBuf labOfs (FixupEntry{fueBuffer = buf, fueOfs = ofs, fueKind = kind}) =+performFixup labBuf labOfs (FixupEntry{fueBuffer = buf, fueOfs = ofs, fueKind = knd}) =     do let diff = (labBuf `plusPtr` labOfs) `minusPtr` (buf `plusPtr` (ofs + 4))-       liftIO $ case kind of+       liftIO $ case knd of                   Fixup8 -> pokeByteOff buf ofs (fromIntegral diff :: Word8)                   Fixup16 -> pokeByteOff buf ofs (fromIntegral diff :: Word16)                   Fixup32 -> pokeByteOff buf ofs (fromIntegral diff :: Word32)@@ -409,6 +460,11 @@        return ()  +-- | This operator gives neat syntax for defining labels.  When @l@ is a label, the code+--+-- > l @@ mov eax ebx+--+-- associates the label l with the following @mov@ instruction. (@@) :: Label -> CodeGen e s a -> CodeGen e s a (@@) lab gen = do defineLabel lab                   gen@@ -419,40 +475,72 @@ -- be patched to target the address associated with this label when -- it is defined later. emitFixup :: Label -> Int -> FixupKind -> CodeGen e s ()-emitFixup (Label lab) ofs kind = +emitFixup (Label lab _) ofs knd =      do state <- getInternalState         let base = buffer state            ptr = bufferOfs state        case Map.lookup lab (definedLabels state) of-         Just (labBuf, labOfs) -> performFixup labBuf labOfs (FixupEntry{fueBuffer = base,-                                                                         fueOfs = ptr + ofs,-                                                                         fueKind = kind})+         Just (labBuf, labOfs, _) -> performFixup labBuf labOfs (FixupEntry{fueBuffer = base,+                                                                            fueOfs = ptr + ofs,+                                                                            fueKind = knd})          Nothing -> setInternalState state{pendingFixups = Map.insertWith (++) lab [FixupEntry{fueBuffer = base,                                                                                           fueOfs = ptr + ofs,-                                                                                          fueKind = kind}]+                                                                                          fueKind = knd}]                                                                                           (pendingFixups state)}  -- | Return the address of a label, fail if the label is not yet defined. labelAddress :: Label -> CodeGen e s (Ptr a)-labelAddress (Label lab) = do+labelAddress (Label lab name) = do   state <- getInternalState   case Map.lookup lab (definedLabels state) of-    Just (labBuf, labOfs) -> return $ plusPtr labBuf labOfs-    Nothing -> fail $ "Label " ++ show lab ++ " not yet defined"+    Just (labBuf, labOfs, _) -> return $ plusPtr labBuf labOfs+    Nothing -> fail $ "Label " ++ show lab ++ "(" ++ name ++ ") not yet defined"  --- | Disassemble all code buffers.+-- | Disassemble all code buffers.  The result is a list of+-- disassembled instructions which can be converted to strings using+-- the 'Dis.showIntel' or 'Dis.showAtt' functions from module+-- "Harpy.X86Disassembler". disassemble :: CodeGen e s [Dis.Instruction] disassemble = do   s <- getInternalState   let buffers = bufferList s-  r <- mapM (\ (buffer, length) -> do-             r <- liftIO $ Dis.disassembleBlock buffer length+  r <- mapM (\ (buff, len) -> do+             r <- liftIO $ Dis.disassembleBlock buff len              case r of                     Left err -> cgFail $ show err                     Right instr -> return instr             ) $ buffers ++ [(buffer s, bufferOfs s)]-  return $ concat r+  r' <- insertLabels (concat r)+  return r'+ where insertLabels :: [Dis.Instruction] -> CodeGen e s [Dis.Instruction]+       insertLabels = liftM concat . mapM ins+       ins :: Dis.Instruction -> CodeGen e s [Dis.Instruction]+       ins i@(Dis.BadInstruction{}) = return [i]+       ins i@(Dis.PseudoInstruction{}) = return [i]+       ins i@(Dis.Instruction{Dis.address = addr}) =+           do state <- getInternalState+              let labs = Map.toList (definedLabels state)+                  lab = find (\ (_, (buf, ofs, _)) -> fromIntegral (ptrToWordPtr (buf `plusPtr` ofs)) == addr) labs+              case lab of+                Nothing -> return [i]+                Just (l, (buf, ofs, name)) -> return [Dis.PseudoInstruction addr+                                                         (case name of+                                                           "" ->+                                                               "label " ++ show l ++ +                                                                " [" ++ +                                                                hex32 (fromIntegral (ptrToWordPtr (buf `plusPtr` ofs))) ++ +                                                                "]"+                                                           _ -> name ++ ": [" ++ +                                                                  hex32 (fromIntegral (ptrToWordPtr (buf `plusPtr` ofs))) ++ +                                                                  "]"), +                                                            i]+       hex32 :: Int -> String+       hex32 i =+              let w :: Word32+                  w = fromIntegral i+                  s = showHex w ""+              in take (8 - length s) (repeat '0') ++ s  #ifndef __HADDOCK__ @@ -460,7 +548,7 @@ callDecl ns qt =  do     t0 <- qt     let (tvars, cxt, t) = case t0 of-                         ForallT vs c t -> (vs, c, t)+                         ForallT vs c t' -> (vs, c, t')                          _ -> ([], [], t0)     let name = mkName ns     let funptr = AppT (ConT $ mkName "FunPtr") t
+ Harpy/X86Assembler.hs view
@@ -0,0 +1,3746 @@+--------------------------------------------------------------------------+-- |+-- Module      :  Harpy.X86Assembler+-- Copyright   :  (c) 2006-2007 Martin Grabmueller and Dirk Kleeblatt+-- License     :  GPL+-- +-- Maintainer  :  {magr,klee}@cs.tu-berlin.de+-- Stability   :  provisional+-- Portability :  non-portable+--+-- A type class based layer on top of X86CodeGen+-- which determines the addressing modes from the types of the+-- operands.+--------------------------------------------------------------------------+module Harpy.X86Assembler where++import Harpy.X86CodeGen+import Harpy.CodeGenMonad+import Data.Word+import Foreign.Ptr++import qualified Text.PrettyPrint.HughesPJ as PP+++-- address modes used in this module:++-- Word8/16/32	   	     immediate values+-- Reg8/16/32	             register+-- Addr Word32		     absolut+-- Ind Reg32		     register indirect+-- (Disp, Reg32)		     register indirect with displacement+-- (Reg32, Reg32, Scale)	     (base, index, scale), effective address is (base + index * scale)+-- (Disp, Reg32, Scale)	     (disp, index, scale), effective address is (disp + index * scale)+-- (Disp, Reg32, Reg32, Scale)  (base, index, scale) + displacement (only ebp is allowed as base register)+-- Label                        not-yet-specified label++onlyEbp = failCodeGen (PP.text "only epb is allowed as base register for disp/base/index/scale addressing")+onlyCl  = failCodeGen (PP.text "only cl is allowed as shift count")+++-- x86 Registers++newtype Reg8 = Reg8 Word8+al, cl, dl, bl, ah, ch, dh, bh :: Reg8++al = Reg8 0+cl = Reg8 1+dl = Reg8 2+bl = Reg8 3+ah = Reg8 4+ch = Reg8 5+dh = Reg8 6+bh = Reg8 7++newtype Reg16 = Reg16 Word8+ax, cx, dx, bx, sp, bp, si, di :: Reg16++ax = Reg16 0+cx = Reg16 1+dx = Reg16 2+bx = Reg16 3+sp = Reg16 4+bp = Reg16 5+si = Reg16 6+di = Reg16 7++newtype Reg32 = Reg32 Word8 deriving Eq+eax, ecx, edx, ebx, esp, ebp, esi, edi :: Reg32++eax = Reg32 0+ecx = Reg32 1+edx = Reg32 2+ebx = Reg32 3+esp = Reg32 4+ebp = Reg32 5+esi = Reg32 6+edi = Reg32 7++newtype XMMReg = XMMReg Word8++xmm0 = XMMReg 0+xmm1 = XMMReg 1+xmm2 = XMMReg 2+xmm3 = XMMReg 3+xmm4 = XMMReg 4+xmm5 = XMMReg 5+xmm6 = XMMReg 6+xmm7 = XMMReg 7++-- TODO: instances for other registers++instance Show Reg32 where+ show (Reg32 0) = "eax"+ show (Reg32 1) = "ecx"+ show (Reg32 2) = "edx"+ show (Reg32 3) = "ebx"+ show (Reg32 4) = "esp"+ show (Reg32 5) = "ebp"+ show (Reg32 6) = "esi"+ show (Reg32 7) = "edi"++-- memory addresses++newtype Addr  = Addr Word32+newtype Ind   = Ind Reg32+newtype Disp  = Disp Word32++data    Scale = S1 | S2 | S4 | S8++scaleToShift :: Scale -> Word8+scaleToShift S1 = 0+scaleToShift S2 = 1+scaleToShift S4 = 2+scaleToShift S8 = 3++newtype FPReg = FPReg Word8++data FPTopReg = FPTopReg++fpTop = FPTopReg++fp0 = FPReg 0+fp1 = FPReg 1+fp2 = FPReg 2+fp3 = FPReg 3+fp4 = FPReg 4+fp5 = FPReg 5+fp6 = FPReg 6+fp7 = FPReg 7++-- int 3++breakpoint = ensureBufferSize x86_max_instruction_bytes >> x86_breakpoint+++-- clear direction flag++cld = ensureBufferSize x86_max_instruction_bytes >> x86_cld+++-- store string++stosb = ensureBufferSize x86_max_instruction_bytes >> x86_stosb+stosl = ensureBufferSize x86_max_instruction_bytes >> x86_stosl+stosd = ensureBufferSize x86_max_instruction_bytes >> x86_stosd+++-- move string++movsb = ensureBufferSize x86_max_instruction_bytes >> x86_movsb+movsl = ensureBufferSize x86_max_instruction_bytes >> x86_movsl+--movsd = ensureBufferSize x86_max_instruction_bytes >> x86_movsd+++-- read time stamp counter++rdtsc = ensureBufferSize x86_max_instruction_bytes >> x86_rdtsc+++-- compare and exchange++class Cmpxchg a b where+  cmpxchg :: a -> b -> CodeGen e s ()++instance Cmpxchg Reg32 Reg32 where+  cmpxchg (Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmpxchg_reg_reg dest source++instance Cmpxchg Addr Reg32 where+  cmpxchg (Addr dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmpxchg_mem_reg dest source++instance Cmpxchg (Disp, Reg32) Reg32 where+  cmpxchg (Disp disp, Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmpxchg_membase_reg dest disp source++instance Cmpxchg Ind Reg32 where+  cmpxchg (Ind (Reg32 dest)) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmpxchg_membase_reg dest 0 source++++-- exchange memory/register with register++class Xchg a b where+  xchg :: a -> b -> CodeGen e s ()++instance Xchg Reg8 Reg8 where+  xchg (Reg8 dest) (Reg8 source) = ensureBufferSize x86_max_instruction_bytes >> x86_xchg_reg_reg dest source 1++instance Xchg Reg32 Reg32 where+  xchg (Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_xchg_reg_reg dest source 4++instance Xchg Addr Reg8 where+  xchg (Addr dest) (Reg8 source) = ensureBufferSize x86_max_instruction_bytes >> x86_xchg_mem_reg dest source 1++instance Xchg Addr Reg32 where+  xchg (Addr dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_xchg_mem_reg dest source 4++instance Xchg (Disp, Reg32) Reg8 where+  xchg (Disp disp, Reg32 dest) (Reg8 source) = ensureBufferSize x86_max_instruction_bytes >> x86_xchg_membase_reg dest disp source 1++instance Xchg Ind Reg8 where+  xchg (Ind (Reg32 dest)) (Reg8 source) = ensureBufferSize x86_max_instruction_bytes >> x86_xchg_membase_reg dest 0 source 1++instance Xchg (Disp, Reg32) Reg32 where+  xchg (Disp disp, Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_xchg_membase_reg dest disp source 4++instance Xchg Ind Reg32 where+  xchg (Ind (Reg32 dest)) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_xchg_membase_reg dest 0 source 4+++-- exchange and add++class Xadd a b where+  xadd :: a -> b -> CodeGen e s ()++instance Xadd Reg8 Reg8 where+  xadd (Reg8 dest) (Reg8 source) = ensureBufferSize x86_max_instruction_bytes >> x86_xadd_reg_reg dest source 1++instance Xadd Reg32 Reg32 where+  xadd (Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_xadd_reg_reg dest source 4++instance Xadd Addr Reg8 where+  xadd (Addr dest) (Reg8 source) = ensureBufferSize x86_max_instruction_bytes >> x86_xadd_mem_reg dest source 1++instance Xadd Addr Reg32 where+  xadd (Addr dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_xadd_mem_reg dest source 4++instance Xadd (Disp, Reg32) Reg8 where+  xadd (Disp disp, Reg32 dest) (Reg8 source) = ensureBufferSize x86_max_instruction_bytes >> x86_xadd_membase_reg dest disp source 1++instance Xadd Ind Reg8 where+  xadd (Ind (Reg32 dest)) (Reg8 source) = ensureBufferSize x86_max_instruction_bytes >> x86_xadd_membase_reg dest 0 source 1++instance Xadd (Disp, Reg32) Reg32 where+  xadd (Disp disp, Reg32 dest) (Reg32 source) =  ensureBufferSize x86_max_instruction_bytes >> x86_xadd_membase_reg dest disp source 4++instance Xadd Ind Reg32 where+  xadd (Ind (Reg32 dest)) (Reg32 source) =  ensureBufferSize x86_max_instruction_bytes >> x86_xadd_membase_reg dest 0 source 4+++-- Increment by 1++class Inc a where+  inc :: a -> CodeGen e s ()++instance Inc Addr where+  inc (Addr dest) = ensureBufferSize x86_max_instruction_bytes >> x86_inc_mem dest++instance Inc (Disp, Reg32) where+  inc (Disp disp, Reg32 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_inc_membase dest disp++instance Inc Ind where+  inc (Ind (Reg32 dest)) = ensureBufferSize x86_max_instruction_bytes >> x86_inc_membase dest 0++instance Inc Reg32 where+  inc (Reg32 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_inc_reg dest+++-- Decrement by 1++class Dec a where+  dec :: a -> CodeGen e s ()++instance Dec Addr where+  dec (Addr dest) = ensureBufferSize x86_max_instruction_bytes >> x86_dec_mem dest++instance Dec (Disp, Reg32) where+  dec (Disp disp, Reg32 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_dec_membase dest disp++instance Dec Ind where+  dec (Ind (Reg32 dest)) = ensureBufferSize x86_max_instruction_bytes >> x86_dec_membase dest 0++instance Dec Reg32 where+  dec (Reg32 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_dec_reg dest+++-- One's complement negation++class Not a where+  not :: a -> CodeGen e s ()++instance Not Addr where+  not (Addr dest) = ensureBufferSize x86_max_instruction_bytes >> x86_not_mem dest++instance Not (Disp, Reg32) where+  not (Disp disp, Reg32 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_not_membase dest disp++instance Not Ind where+  not (Ind (Reg32 dest)) = ensureBufferSize x86_max_instruction_bytes >> x86_not_membase dest 0++instance Not Reg32 where+  not (Reg32 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_not_reg dest+++-- Two's complement negation++class Neg a where+  neg :: a -> CodeGen e s ()++instance Neg Addr where+  neg (Addr dest) = ensureBufferSize x86_max_instruction_bytes >> x86_neg_mem dest++instance Neg (Disp, Reg32) where+  neg (Disp disp, Reg32 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_neg_membase dest disp++instance Neg Ind where+  neg (Ind (Reg32 dest)) = ensureBufferSize x86_max_instruction_bytes >> x86_neg_membase dest 0++instance Neg Reg32 where+  neg (Reg32 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_neg_reg dest+++-- No operation++nop = ensureBufferSize x86_max_instruction_bytes >> x86_nop+++-- ALU operations++-- Calling "x86_alu_reg8_reg8 _ _ _ *False* *False*" is a little bit hackish: the last two+-- arguments are set to True for the "high byte registers" ah, bh, ch and dh.+-- x86_reg8_emit then sets the 3rd bit in the register number. This bit is set in our+-- encoding anyway to the right value, so we simply skip this part.++class Add a b where+  add :: a -> b -> CodeGen e s ()++instance Add Reg32 Word32 where+  add (Reg32 dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_alu_reg_imm x86_add dest (fromIntegral imm)++instance Add Addr Word32 where+  add (Addr dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_alu_mem_imm x86_add dest (fromIntegral imm)++instance Add (Disp, Reg32) Word32 where+  add (Disp disp, Reg32 dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_alu_membase_imm x86_add dest disp (fromIntegral imm)++instance Add Ind Word32 where+  add (Ind (Reg32 dest)) imm = ensureBufferSize x86_max_instruction_bytes >> x86_alu_membase_imm x86_add dest 0 (fromIntegral imm)++instance Add (Disp, Reg32) Word8 where+  add (Disp disp, Reg32 dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_alu_membase8_imm x86_add dest disp (fromIntegral imm)++instance Add Ind Word8 where+  add (Ind (Reg32 dest)) imm = ensureBufferSize x86_max_instruction_bytes >> x86_alu_membase8_imm x86_add dest 0 (fromIntegral imm)++instance Add Addr Reg32 where+  add (Addr dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_mem_reg x86_add dest source++instance Add (Disp, Reg32) Reg32 where+  add (Disp disp, Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_membase_reg x86_add dest disp source++instance Add Ind Reg32 where+  add (Ind (Reg32 dest)) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_membase_reg x86_add dest 0 source++instance Add Reg32 Reg32 where+  add (Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_reg_reg x86_add dest source++instance Add Reg8 Reg8 where+  add (Reg8 dest) (Reg8 source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_reg8_reg8 x86_add dest source False False++instance Add Reg32 Addr where+  add (Reg32 dest) (Addr source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_reg_mem x86_add dest source++instance Add Reg32 (Disp, Reg32) where+  add (Reg32 dest) (Disp disp, Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_reg_membase x86_add dest source disp++instance Add Reg32 Ind where+  add (Reg32 dest) (Ind (Reg32 source)) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_reg_membase x86_add dest source 0+++class Or a b where+  or :: a -> b -> CodeGen e s ()++instance Or Reg32 Word32 where+  or (Reg32 dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_alu_reg_imm x86_or dest (fromIntegral imm)++instance Or Addr Word32 where+  or (Addr dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_alu_mem_imm x86_or dest (fromIntegral imm)++instance Or (Disp, Reg32) Word32 where+  or (Disp disp, Reg32 dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_alu_membase_imm x86_or dest disp (fromIntegral imm)++instance Or Ind Word32 where+  or (Ind (Reg32 dest)) imm = ensureBufferSize x86_max_instruction_bytes >> x86_alu_membase_imm x86_or dest 0 (fromIntegral imm)++instance Or (Disp, Reg32) Word8 where+  or (Disp disp, Reg32 dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_alu_membase8_imm x86_or dest disp (fromIntegral imm)++instance Or Ind Word8 where+  or (Ind (Reg32 dest)) imm = ensureBufferSize x86_max_instruction_bytes >> x86_alu_membase8_imm x86_or dest 0 (fromIntegral imm)++instance Or Addr Reg32 where+  or (Addr dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_mem_reg x86_or dest source++instance Or (Disp, Reg32) Reg32 where+  or (Disp disp, Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_membase_reg x86_or dest disp source++instance Or Ind Reg32 where+  or (Ind (Reg32 dest)) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_membase_reg x86_or dest 0 source++instance Or Reg32 Reg32 where+  or (Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_reg_reg x86_or dest source++instance Or Reg8 Reg8 where+  or (Reg8 dest) (Reg8 source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_reg8_reg8 x86_or dest source False False++instance Or Reg32 Addr where+  or (Reg32 dest) (Addr source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_reg_mem x86_or dest source++instance Or Reg32 (Disp, Reg32) where+  or (Reg32 dest) (Disp disp, Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_reg_membase x86_or dest source disp++instance Or Reg32 Ind where+  or (Reg32 dest) (Ind (Reg32 source)) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_reg_membase x86_or dest source 0+++class Adc a b where+  adc :: a -> b -> CodeGen e s ()++instance Adc Reg32 Word32 where+  adc (Reg32 dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_alu_reg_imm x86_adc dest (fromIntegral imm)++instance Adc Addr Word32 where+  adc (Addr dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_alu_mem_imm x86_adc dest (fromIntegral imm)++instance Adc (Disp, Reg32) Word32 where+  adc (Disp disp, Reg32 dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_alu_membase_imm x86_adc dest disp (fromIntegral imm)++instance Adc Ind Word32 where+  adc (Ind (Reg32 dest)) imm = ensureBufferSize x86_max_instruction_bytes >> x86_alu_membase_imm x86_adc dest 0 (fromIntegral imm)++instance Adc (Disp, Reg32) Word8 where+  adc (Disp disp, Reg32 dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_alu_membase8_imm x86_adc dest disp (fromIntegral imm)++instance Adc Ind Word8 where+  adc (Ind (Reg32 dest)) imm = ensureBufferSize x86_max_instruction_bytes >> x86_alu_membase8_imm x86_adc dest 0 (fromIntegral imm)++instance Adc Addr Reg32 where+  adc (Addr dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_mem_reg x86_adc dest source++instance Adc (Disp, Reg32) Reg32 where+  adc (Disp disp, Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_membase_reg x86_adc dest disp source++instance Adc Ind Reg32 where+  adc (Ind (Reg32 dest)) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_membase_reg x86_adc dest 0 source++instance Adc Reg32 Reg32 where+  adc (Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_reg_reg x86_adc dest source++instance Adc Reg8 Reg8 where+  adc (Reg8 dest) (Reg8 source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_reg8_reg8 x86_adc dest source False False++instance Adc Reg32 Addr where+  adc (Reg32 dest) (Addr source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_reg_mem x86_adc dest source++instance Adc Reg32 (Disp, Reg32) where+  adc (Reg32 dest) (Disp disp, Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_reg_membase x86_adc dest source disp++instance Adc Reg32 Ind where+  adc (Reg32 dest) (Ind (Reg32 source)) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_reg_membase x86_adc dest source 0+++class Sbb a b where+  sbb :: a -> b -> CodeGen e s ()++instance Sbb Reg32 Word32 where+  sbb (Reg32 dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_alu_reg_imm x86_sbb dest (fromIntegral imm)++instance Sbb Addr Word32 where+  sbb (Addr dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_alu_mem_imm x86_sbb dest (fromIntegral imm)++instance Sbb (Disp, Reg32) Word32 where+  sbb (Disp disp, Reg32 dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_alu_membase_imm x86_sbb dest disp (fromIntegral imm)++instance Sbb Ind Word32 where+  sbb (Ind (Reg32 dest)) imm = ensureBufferSize x86_max_instruction_bytes >> x86_alu_membase_imm x86_sbb dest 0 (fromIntegral imm)++instance Sbb (Disp, Reg32) Word8 where+  sbb (Disp disp, Reg32 dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_alu_membase8_imm x86_sbb dest disp (fromIntegral imm)++instance Sbb Ind Word8 where+  sbb (Ind (Reg32 dest)) imm = ensureBufferSize x86_max_instruction_bytes >> x86_alu_membase8_imm x86_sbb dest 0 (fromIntegral imm)++instance Sbb Addr Reg32 where+  sbb (Addr dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_mem_reg x86_sbb dest source++instance Sbb (Disp, Reg32) Reg32 where+  sbb (Disp disp, Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_membase_reg x86_sbb dest disp source++instance Sbb Ind Reg32 where+  sbb (Ind (Reg32 dest)) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_membase_reg x86_sbb dest 0 source++instance Sbb Reg32 Reg32 where+  sbb (Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_reg_reg x86_sbb dest source++instance Sbb Reg8 Reg8 where+  sbb (Reg8 dest) (Reg8 source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_reg8_reg8 x86_sbb dest source False False++instance Sbb Reg32 Addr where+  sbb (Reg32 dest) (Addr source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_reg_mem x86_sbb dest source++instance Sbb Reg32 (Disp, Reg32) where+  sbb (Reg32 dest) (Disp disp, Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_reg_membase x86_sbb dest source disp++instance Sbb Reg32 Ind where+  sbb (Reg32 dest) (Ind (Reg32 source)) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_reg_membase x86_sbb dest source 0+++class And a b where+  and :: a -> b -> CodeGen e s ()++instance And Reg32 Word32 where+  and (Reg32 dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_alu_reg_imm x86_and dest (fromIntegral imm)++instance And Addr Word32 where+  and (Addr dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_alu_mem_imm x86_and dest (fromIntegral imm)++instance And (Disp, Reg32) Word32 where+  and (Disp disp, Reg32 dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_alu_membase_imm x86_and dest disp (fromIntegral imm)++instance And Ind Word32 where+  and (Ind (Reg32 dest)) imm = ensureBufferSize x86_max_instruction_bytes >> x86_alu_membase_imm x86_and dest 0 (fromIntegral imm)++instance And (Disp, Reg32) Word8 where+  and (Disp disp, Reg32 dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_alu_membase8_imm x86_and dest disp (fromIntegral imm)++instance And Ind Word8 where+  and (Ind (Reg32 dest)) imm = ensureBufferSize x86_max_instruction_bytes >> x86_alu_membase8_imm x86_and dest 0 (fromIntegral imm)++instance And Addr Reg32 where+  and (Addr dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_mem_reg x86_and dest source++instance And (Disp, Reg32) Reg32 where+  and (Disp disp, Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_membase_reg x86_and dest disp source++instance And Ind Reg32 where+  and (Ind (Reg32 dest)) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_membase_reg x86_and dest 0 source++instance And Reg32 Reg32 where+  and (Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_reg_reg x86_and dest source++instance And Reg8 Reg8 where+  and (Reg8 dest) (Reg8 source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_reg8_reg8 x86_and dest source False False++instance And Reg32 Addr where+  and (Reg32 dest) (Addr source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_reg_mem x86_and dest source++instance And Reg32 (Disp, Reg32) where+  and (Reg32 dest) (Disp disp, Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_reg_membase x86_and dest source disp++instance And Reg32 Ind where+  and (Reg32 dest) (Ind (Reg32 source)) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_reg_membase x86_and dest source 0+++class Sub a b where+  sub :: a -> b -> CodeGen e s ()++instance Sub Reg32 Word32 where+  sub (Reg32 dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_alu_reg_imm x86_sub dest (fromIntegral imm)++instance Sub Addr Word32 where+  sub (Addr dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_alu_mem_reg x86_sub dest (fromIntegral imm)++instance Sub (Disp, Reg32) Word32 where+  sub (Disp disp, Reg32 dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_alu_membase_imm x86_sub dest disp (fromIntegral imm)++instance Sub Ind Word32 where+  sub (Ind (Reg32 dest)) imm = ensureBufferSize x86_max_instruction_bytes >> x86_alu_membase_imm x86_sub dest 0 (fromIntegral imm)++instance Sub (Disp, Reg32) Word8 where+  sub (Disp disp, Reg32 dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_alu_membase8_imm x86_sub dest disp (fromIntegral imm)++instance Sub Ind Word8 where+  sub (Ind (Reg32 dest)) imm = ensureBufferSize x86_max_instruction_bytes >> x86_alu_membase8_imm x86_sub dest 0 (fromIntegral imm)++instance Sub Addr Reg32 where+  sub (Addr dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_mem_reg x86_sub dest source++instance Sub (Disp, Reg32) Reg32 where+  sub (Disp disp, Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_membase_reg x86_sub dest disp source++instance Sub Ind Reg32 where+  sub (Ind (Reg32 dest)) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_membase_reg x86_sub dest 0 source++instance Sub Reg32 Reg32 where+  sub (Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_reg_reg x86_sub dest source++instance Sub Reg8 Reg8 where+  sub (Reg8 dest) (Reg8 source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_reg8_reg8 x86_sub dest source False False++instance Sub Reg32 Addr where+  sub (Reg32 dest) (Addr source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_reg_mem x86_sub dest source++instance Sub Reg32 (Disp, Reg32) where+  sub (Reg32 dest) (Disp disp, Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_reg_membase x86_sub dest source disp++instance Sub Reg32 Ind where+  sub (Reg32 dest) (Ind (Reg32 source)) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_reg_membase x86_sub dest source 0+++class Xor a b where+  xor :: a -> b -> CodeGen e s ()++instance Xor Reg32 Word32 where+  xor (Reg32 dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_alu_reg_imm x86_xor dest (fromIntegral imm)++instance Xor Addr Word32 where+  xor (Addr dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_alu_mem_imm x86_xor dest (fromIntegral imm)++instance Xor (Disp, Reg32) Word32 where+  xor (Disp disp, Reg32 dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_alu_membase_imm x86_xor dest disp (fromIntegral imm)++instance Xor Ind Word32 where+  xor (Ind (Reg32 dest)) imm = ensureBufferSize x86_max_instruction_bytes >> x86_alu_membase_imm x86_xor dest 0 (fromIntegral imm)++instance Xor (Disp, Reg32) Word8 where+  xor (Disp disp, Reg32 dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_alu_membase8_imm x86_xor dest disp (fromIntegral imm)++instance Xor Ind Word8 where+  xor (Ind (Reg32 dest)) imm = ensureBufferSize x86_max_instruction_bytes >> x86_alu_membase8_imm x86_xor dest 0 (fromIntegral imm)++instance Xor Addr Reg32 where+  xor (Addr dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_mem_reg x86_xor dest source++instance Xor (Disp, Reg32) Reg32 where+  xor (Disp disp, Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_membase_reg x86_xor dest disp source++instance Xor Ind Reg32 where+  xor (Ind (Reg32 dest)) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_membase_reg x86_xor dest 0 source++instance Xor Reg32 Reg32 where+  xor (Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_reg_reg x86_xor dest source++instance Xor Reg8 Reg8 where+  xor (Reg8 dest) (Reg8 source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_reg8_reg8 x86_xor dest source False False++instance Xor Reg32 Addr where+  xor (Reg32 dest) (Addr source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_reg_mem x86_xor dest source++instance Xor Reg32 (Disp, Reg32) where+  xor (Reg32 dest) (Disp disp, Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_reg_membase x86_xor dest source disp++instance Xor Reg32 Ind where+  xor (Reg32 dest) (Ind (Reg32 source)) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_reg_membase x86_xor dest source 0+++class Cmp a b where+  cmp :: a -> b -> CodeGen e s ()++instance Cmp Reg32 Word32 where+  cmp (Reg32 dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_alu_reg_imm x86_cmp dest (fromIntegral imm)++instance Cmp Reg32 Label where+  cmp (Reg32 dest) lab = do+      ensureBufferSize x86_max_instruction_bytes+      x86_alu_reg_imm x86_cmp dest 0xf0f0f0f0+      emitFixup lab (-4) Fixup32Absolute++instance Cmp Addr Word32 where+  cmp (Addr dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_alu_mem_imm x86_cmp dest (fromIntegral imm)++instance Cmp Addr Label where+  cmp (Addr dest) lab = do+      ensureBufferSize x86_max_instruction_bytes >> x86_alu_mem_imm x86_cmp dest 0xf0f0f0f0+      emitFixup lab (-4) Fixup32Absolute++instance Cmp (Disp, Reg32) Word32 where+  cmp (Disp disp, Reg32 dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_alu_membase_imm x86_cmp dest disp (fromIntegral imm)++instance Cmp (Disp, Reg32) Label where+  cmp (Disp disp, Reg32 dest) lab = do+                                   ensureBufferSize x86_max_instruction_bytes >> x86_alu_membase_imm x86_cmp dest disp 0xf0f0f0f0+                                   emitFixup lab (-4) Fixup32Absolute++instance Cmp Ind Word32 where+  cmp (Ind (Reg32 dest)) imm = ensureBufferSize x86_max_instruction_bytes >> x86_alu_membase_imm x86_cmp dest 0 (fromIntegral imm)++instance Cmp Ind Label where+  cmp (Ind (Reg32 dest)) lab = do+                         ensureBufferSize x86_max_instruction_bytes >> x86_alu_membase_imm x86_cmp dest 0 0xf0f0f0f0+                         emitFixup lab (-4) Fixup32Absolute++instance Cmp (Disp, Reg32) Word8 where+  cmp (Disp disp, Reg32 dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_alu_membase8_imm x86_cmp dest disp imm++instance Cmp Ind Word8 where+  cmp (Ind (Reg32 dest)) imm = ensureBufferSize x86_max_instruction_bytes >> x86_alu_membase8_imm x86_cmp dest 0 imm++instance Cmp Addr Reg32 where+  cmp (Addr dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_mem_reg x86_cmp dest source++instance Cmp (Disp, Reg32) Reg32 where+  cmp (Disp disp, Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_membase_reg x86_cmp dest disp source++instance Cmp Ind Reg32 where+  cmp (Ind (Reg32 dest)) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_membase_reg x86_cmp dest 0 source++instance Cmp Reg32 Reg32 where+  cmp (Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_reg_reg x86_cmp dest source++instance Cmp Reg8 Reg8 where+  cmp (Reg8 dest) (Reg8 source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_reg8_reg8 x86_cmp dest source False False++instance Cmp Reg32 Addr where+  cmp (Reg32 dest) (Addr source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_reg_mem x86_cmp dest source++instance Cmp Reg32 (Disp, Reg32) where+  cmp (Reg32 dest) (Disp disp, Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_reg_membase x86_cmp dest source disp++instance Cmp Reg32 Ind where+  cmp (Reg32 dest) (Ind (Reg32 source)) = ensureBufferSize x86_max_instruction_bytes >> x86_alu_reg_membase x86_cmp dest source 0+++-- logical compare++class Test a b where+  test :: a -> b -> CodeGen e s ()++instance Test Reg32 Word32 where+  test (Reg32 dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_test_reg_imm dest imm ++instance Test Addr Word32 where+  test (Addr dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_test_mem_imm dest imm ++instance Test (Disp, Reg32) Word32 where+  test (Disp disp, Reg32 dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_test_membase_imm dest disp imm ++instance Test Ind Word32 where+  test (Ind (Reg32 dest)) imm = ensureBufferSize x86_max_instruction_bytes >> x86_test_membase_imm dest 0 imm ++instance Test Reg32 Reg32 where+  test (Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_test_reg_reg dest source ++instance Test Addr Reg32 where+  test (Addr dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_test_mem_reg dest source ++instance Test (Disp, Reg32) Reg32 where+  test (Disp disp, Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_test_membase_reg dest disp source ++instance Test Ind Reg32 where+  test (Ind (Reg32 dest)) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_test_membase_reg dest 0 source +++-- shift and rotate++class Rol a b where+  rol :: a -> b -> CodeGen e s ()++instance Rol Reg32 Word8 where+  rol (Reg32 dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_shift_reg_imm x86_rol dest imm ++instance Rol Addr Word8 where+  rol (Addr dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_shift_mem_imm x86_rol dest imm ++instance Rol (Disp, Reg32) Word8 where+  rol (Disp disp, Reg32 dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_shift_membase_imm x86_rol dest disp imm ++instance Rol Ind Word8 where+  rol (Ind (Reg32 dest)) imm = ensureBufferSize x86_max_instruction_bytes >> x86_shift_membase_imm x86_rol dest 0 imm ++instance Rol Reg32 Reg8 where+  rol (Reg32 dest) (Reg8 1) = ensureBufferSize x86_max_instruction_bytes >> x86_shift_reg x86_rol dest+  rol _ _ = onlyCl++instance Rol Addr Reg8 where+  rol (Addr dest) (Reg8 1) = ensureBufferSize x86_max_instruction_bytes >> x86_shift_mem x86_rol dest+  rol _ _ = onlyCl++instance Rol (Disp, Reg32) Reg8 where+  rol (Disp disp, Reg32 dest) (Reg8 1) = ensureBufferSize x86_max_instruction_bytes >> x86_shift_membase x86_rol dest disp++instance Rol Ind Reg8 where+  rol (Ind (Reg32 dest)) (Reg8 1) = ensureBufferSize x86_max_instruction_bytes >> x86_shift_membase x86_rol dest 0+  rol _ _ = onlyCl++class Ror a b where+  ror :: a -> b -> CodeGen e s ()++instance Ror Reg32 Word8 where+  ror (Reg32 dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_shift_reg_imm x86_ror dest imm ++instance Ror Addr Word8 where+  ror (Addr dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_shift_mem_imm x86_ror dest imm ++instance Ror (Disp, Reg32) Word8 where+  ror (Disp disp, Reg32 dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_shift_membase_imm x86_ror dest disp imm ++instance Ror Ind Word8 where+  ror (Ind (Reg32 dest)) imm = ensureBufferSize x86_max_instruction_bytes >> x86_shift_membase_imm x86_ror dest 0 imm ++instance Ror Reg32 Reg8 where+  ror (Reg32 dest) (Reg8 1) = ensureBufferSize x86_max_instruction_bytes >> x86_shift_reg x86_ror dest+  ror _ _ = onlyCl++instance Ror Addr Reg8 where+  ror (Addr dest) (Reg8 1) = ensureBufferSize x86_max_instruction_bytes >> x86_shift_mem x86_ror dest+  ror _ _ = onlyCl++instance Ror (Disp, Reg32) Reg8 where+  ror (Disp disp, Reg32 dest) (Reg8 1) = ensureBufferSize x86_max_instruction_bytes >> x86_shift_membase x86_ror dest disp++instance Ror Ind Reg8 where+  ror (Ind (Reg32 dest)) (Reg8 1) = ensureBufferSize x86_max_instruction_bytes >> x86_shift_membase x86_ror dest 0+  ror _ _ = onlyCl++class Rcl a b where+  rcl :: a -> b -> CodeGen e s ()++instance Rcl Reg32 Word8 where+  rcl (Reg32 dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_shift_reg_imm x86_rcl dest imm ++instance Rcl Addr Word8 where+  rcl (Addr dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_shift_mem_imm x86_rcl dest imm ++instance Rcl (Disp, Reg32) Word8 where+  rcl (Disp disp, Reg32 dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_shift_membase_imm x86_rcl dest disp imm ++instance Rcl Ind Word8 where+  rcl (Ind (Reg32 dest)) imm = ensureBufferSize x86_max_instruction_bytes >> x86_shift_membase_imm x86_rcl dest 0 imm ++instance Rcl Reg32 Reg8 where+  rcl (Reg32 dest) (Reg8 1) = ensureBufferSize x86_max_instruction_bytes >> x86_shift_reg x86_rcl dest+  rcl _ _ = onlyCl++instance Rcl Addr Reg8 where+  rcl (Addr dest) (Reg8 1) = ensureBufferSize x86_max_instruction_bytes >> x86_shift_mem x86_rcl dest+  rcl _ _ = onlyCl++instance Rcl (Disp, Reg32) Reg8 where+  rcl (Disp disp, Reg32 dest) (Reg8 1) = ensureBufferSize x86_max_instruction_bytes >> x86_shift_membase x86_rcl dest disp++instance Rcl Ind Reg8 where+  rcl (Ind (Reg32 dest)) (Reg8 1) = ensureBufferSize x86_max_instruction_bytes >> x86_shift_membase x86_rcl dest 0+  rcl _ _ = onlyCl++class Rcr a b where+  rcr :: a -> b -> CodeGen e s ()++instance Rcr Reg32 Word8 where+  rcr (Reg32 dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_shift_reg_imm x86_rcr dest imm ++instance Rcr Addr Word8 where+  rcr (Addr dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_shift_mem_imm x86_rcr dest imm ++instance Rcr (Disp, Reg32) Word8 where+  rcr (Disp disp, Reg32 dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_shift_membase_imm x86_rcr dest disp imm ++instance Rcr Ind Word8 where+  rcr (Ind (Reg32 dest)) imm = ensureBufferSize x86_max_instruction_bytes >> x86_shift_membase_imm x86_rcr dest 0 imm ++instance Rcr Reg32 Reg8 where+  rcr (Reg32 dest) (Reg8 1) = ensureBufferSize x86_max_instruction_bytes >> x86_shift_reg x86_rcr dest+  rcr _ _ = onlyCl++instance Rcr Addr Reg8 where+  rcr (Addr dest) (Reg8 1) = ensureBufferSize x86_max_instruction_bytes >> x86_shift_mem x86_rcr dest+  rcr _ _ = onlyCl++instance Rcr (Disp, Reg32) Reg8 where+  rcr (Disp disp, Reg32 dest) (Reg8 1) = ensureBufferSize x86_max_instruction_bytes >> x86_shift_membase x86_rcr dest disp++instance Rcr Ind Reg8 where+  rcr (Ind (Reg32 dest)) (Reg8 1) = ensureBufferSize x86_max_instruction_bytes >> x86_shift_membase x86_rcr dest 0+  rcr _ _ = onlyCl++class Shl a b where+  shl :: a -> b -> CodeGen e s ()++instance Shl Reg32 Word8 where+  shl (Reg32 dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_shift_reg_imm x86_shl dest imm ++instance Shl Addr Word8 where+  shl (Addr dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_shift_mem_imm x86_shl dest imm ++instance Shl (Disp, Reg32) Word8 where+  shl (Disp disp, Reg32 dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_shift_membase_imm x86_shl dest disp imm ++instance Shl Ind Word8 where+  shl (Ind (Reg32 dest)) imm = ensureBufferSize x86_max_instruction_bytes >> x86_shift_membase_imm x86_shl dest 0 imm ++instance Shl Reg32 Reg8 where+  shl (Reg32 dest) (Reg8 1) = ensureBufferSize x86_max_instruction_bytes >> x86_shift_reg x86_shl dest+  shl _ _ = onlyCl++instance Shl Addr Reg8 where+  shl (Addr dest) (Reg8 1) = ensureBufferSize x86_max_instruction_bytes >> x86_shift_mem x86_shl dest+  shl _ _ = onlyCl++instance Shl (Disp, Reg32) Reg8 where+  shl (Disp disp, Reg32 dest) (Reg8 1) = ensureBufferSize x86_max_instruction_bytes >> x86_shift_membase x86_shl dest disp++instance Shl Ind Reg8 where+  shl (Ind (Reg32 dest)) (Reg8 1) = ensureBufferSize x86_max_instruction_bytes >> x86_shift_membase x86_shl dest 0+  shl _ _ = onlyCl++class Shr a b where+  shr :: a -> b -> CodeGen e s ()++instance Shr Reg32 Word8 where+  shr (Reg32 dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_shift_reg_imm x86_shr dest imm ++instance Shr Addr Word8 where+  shr (Addr dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_shift_mem_imm x86_shr dest imm ++instance Shr (Disp, Reg32) Word8 where+  shr (Disp disp, Reg32 dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_shift_membase_imm x86_shr dest disp imm ++instance Shr Ind Word8 where+  shr (Ind (Reg32 dest)) imm = ensureBufferSize x86_max_instruction_bytes >> x86_shift_membase_imm x86_shr dest 0 imm ++instance Shr Reg32 Reg8 where+  shr (Reg32 dest) (Reg8 1) = ensureBufferSize x86_max_instruction_bytes >> x86_shift_reg x86_shr dest+  shr _ _ = onlyCl++instance Shr Addr Reg8 where+  shr (Addr dest) (Reg8 1) = ensureBufferSize x86_max_instruction_bytes >> x86_shift_mem x86_shr dest+  shr _ _ = onlyCl++instance Shr (Disp, Reg32) Reg8 where+  shr (Disp disp, Reg32 dest) (Reg8 1) = ensureBufferSize x86_max_instruction_bytes >> x86_shift_membase x86_shr dest disp++instance Shr Ind Reg8 where+  shr (Ind (Reg32 dest)) (Reg8 1) = ensureBufferSize x86_max_instruction_bytes >> x86_shift_membase x86_shr dest 0+  shr _ _ = onlyCl++class Sar a b where+  sar :: a -> b -> CodeGen e s ()++instance Sar Reg32 Word8 where+  sar (Reg32 dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_shift_reg_imm x86_sar dest imm ++instance Sar Addr Word8 where+  sar (Addr dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_shift_mem_imm x86_sar dest imm ++instance Sar (Disp, Reg32) Word8 where+  sar (Disp disp, Reg32 dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_shift_membase_imm x86_sar dest disp imm ++instance Sar Ind Word8 where+  sar (Ind (Reg32 dest)) imm = ensureBufferSize x86_max_instruction_bytes >> x86_shift_membase_imm x86_sar dest 0 imm ++instance Sar Reg32 Reg8 where+  sar (Reg32 dest) (Reg8 1) = ensureBufferSize x86_max_instruction_bytes >> x86_shift_reg x86_sar dest+  sar _ _ = onlyCl++instance Sar Addr Reg8 where+  sar (Addr dest) (Reg8 1) = ensureBufferSize x86_max_instruction_bytes >> x86_shift_mem x86_sar dest+  sar _ _ = onlyCl++instance Sar (Disp, Reg32) Reg8 where+  sar (Disp disp, Reg32 dest) (Reg8 1) = ensureBufferSize x86_max_instruction_bytes >> x86_shift_membase x86_sar dest disp++instance Sar Ind Reg8 where+  sar (Ind (Reg32 dest)) (Reg8 1) = ensureBufferSize x86_max_instruction_bytes >> x86_shift_membase x86_sar dest 0+  sar _ _ = onlyCl++class Sal a b where+  sal :: a -> b -> CodeGen e s ()++instance Sal Reg32 Word8 where+  sal (Reg32 dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_shift_reg_imm x86_shl dest imm ++instance Sal Addr Word8 where+  sal (Addr dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_shift_mem_imm x86_shl dest imm ++instance Sal (Disp, Reg32) Word8 where+  sal (Disp disp, Reg32 dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_shift_membase_imm x86_shl dest disp imm ++instance Sal Ind Word8 where+  sal (Ind (Reg32 dest)) imm = ensureBufferSize x86_max_instruction_bytes >> x86_shift_membase_imm x86_shl dest 0 imm ++instance Sal Reg32 Reg8 where+  sal (Reg32 dest) (Reg8 1) = ensureBufferSize x86_max_instruction_bytes >> x86_shift_reg x86_shl dest+  sal _ _ = onlyCl++instance Sal Addr Reg8 where+  sal (Addr dest) (Reg8 1) = ensureBufferSize x86_max_instruction_bytes >> x86_shift_mem x86_shl dest+  sal _ _ = onlyCl++instance Sal (Disp, Reg32) Reg8 where+  sal (Disp disp, Reg32 dest) (Reg8 1) = ensureBufferSize x86_max_instruction_bytes >> x86_shift_membase x86_shl dest disp++instance Sal Ind Reg8 where+  sal (Ind (Reg32 dest)) (Reg8 1) = ensureBufferSize x86_max_instruction_bytes >> x86_shift_membase x86_shl dest 0+  sal _ _ = onlyCl+++-- double precision shift right++class Shrd a b c where+  shrd :: a -> b -> c -> CodeGen e s ()++instance Shrd Reg32 Reg32 Reg8 where+  shrd (Reg32 dest) (Reg32 source) (Reg8 1) = ensureBufferSize x86_max_instruction_bytes >> x86_shrd_reg dest source+  shrd _ _ _ = onlyCl++instance Shrd Reg32 Reg32 Word8 where+  shrd (Reg32 dest) (Reg32 source) imm = ensureBufferSize x86_max_instruction_bytes >> x86_shrd_reg_imm dest source imm +++-- double precision shift left++class Shld a b c where+  shld :: a -> b -> c -> CodeGen e s ()++instance Shld Reg32 Reg32 Reg8 where+  shld (Reg32 dest) (Reg32 source) (Reg8 1) = ensureBufferSize x86_max_instruction_bytes >> x86_shld_reg dest source+  shld _ _ _ = onlyCl++instance Shld Reg32 Reg32 Word8 where+  shld (Reg32 dest) (Reg32 source) imm = ensureBufferSize x86_max_instruction_bytes >> x86_shld_reg_imm dest source imm +++-- unsigned multiply++class Mul a where+  mul :: a -> CodeGen e s ()++instance Mul Reg32 where+  mul (Reg32 arg) = ensureBufferSize x86_max_instruction_bytes >> x86_mul_reg arg False++instance Mul Addr where+  mul (Addr arg) = ensureBufferSize x86_max_instruction_bytes >> x86_mul_mem arg False++instance Mul (Disp, Reg32) where+  mul (Disp disp, Reg32 arg) = ensureBufferSize x86_max_instruction_bytes >> x86_mul_membase arg disp False++instance Mul Ind where+  mul (Ind (Reg32 arg)) = ensureBufferSize x86_max_instruction_bytes >> x86_mul_membase arg 0 False+++-- signed multiply++data InPlace = InPlace++-- if a == InPlace then+--   b = b * c+-- else+--   a = b * c++class Imul a b c where+  imul :: a -> b -> c -> CodeGen e s ()++instance Imul InPlace Reg32 Reg32 where+  imul _ (Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_imul_reg_reg dest source++instance Imul InPlace Reg32 Addr where+  imul _ (Reg32 dest) (Addr source) = ensureBufferSize x86_max_instruction_bytes >> x86_imul_reg_mem dest source++instance Imul InPlace Reg32 (Disp, Reg32) where+  imul _ (Reg32 dest) (Disp disp, Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_imul_reg_membase dest source disp++instance Imul InPlace Reg32 Ind where+  imul _ (Reg32 dest) (Ind (Reg32 source)) = ensureBufferSize x86_max_instruction_bytes >> x86_imul_reg_membase dest source 0++instance Imul Reg32 Reg32 Word32 where+  imul (Reg32 dest) (Reg32 source) imm = ensureBufferSize x86_max_instruction_bytes >> x86_imul_reg_reg_imm dest source imm ++instance Imul Reg32 Addr Word32 where+  imul (Reg32 dest) (Addr source) imm = ensureBufferSize x86_max_instruction_bytes >> x86_imul_reg_mem_imm dest source imm ++instance Imul Reg32 (Disp, Reg32) Word32 where+  imul (Reg32 dest) (Disp disp, Reg32 source) imm = ensureBufferSize x86_max_instruction_bytes >> x86_imul_reg_membase_imm dest source disp imm ++instance Imul Reg32 Ind Word32 where+  imul (Reg32 dest) (Ind (Reg32 source)) imm = ensureBufferSize x86_max_instruction_bytes >> x86_imul_reg_membase_imm dest source 0 imm +++-- divide EDX:EAX by rm;+-- eax = quotient, edx = remainder++-- unsigned divide++class Div a where+  div :: a -> CodeGen e s ()++instance Div Reg32 where+  div (Reg32 arg) = ensureBufferSize x86_max_instruction_bytes >> x86_div_reg arg False++instance Div Addr where+  div (Addr arg) = ensureBufferSize x86_max_instruction_bytes >> x86_div_mem arg False++instance Div (Disp, Reg32) where+  div (Disp disp, Reg32 arg) = ensureBufferSize x86_max_instruction_bytes >> x86_div_membase arg disp False++instance Div Ind where+  div (Ind (Reg32 arg)) = ensureBufferSize x86_max_instruction_bytes >> x86_div_membase arg 0 False+++-- signed divide++class Idiv a where+  idiv :: a -> CodeGen e s ()++instance Idiv Reg32 where+  idiv (Reg32 arg) = ensureBufferSize x86_max_instruction_bytes >> x86_div_reg arg True++instance Idiv Addr where+  idiv (Addr arg) = ensureBufferSize x86_max_instruction_bytes >> x86_div_mem arg True++instance Idiv (Disp, Reg32) where+  idiv (Disp disp, Reg32 arg) = ensureBufferSize x86_max_instruction_bytes >> x86_div_membase arg disp True++instance Idiv Ind where+  idiv (Ind (Reg32 arg)) = ensureBufferSize x86_max_instruction_bytes >> x86_div_membase arg 0 True+++-- "mov" instruction for different sources and destinations++class Mov a b where+  mov :: a -> b -> CodeGen e s ()+++instance Mov Reg8 Reg8 where+  mov (Reg8 dest) (Reg8 source) = ensureBufferSize x86_max_instruction_bytes >> x86_mov_reg_reg dest source 1++instance Mov Reg16 Reg16 where+  mov (Reg16 dest) (Reg16 source) = ensureBufferSize x86_max_instruction_bytes >> x86_mov_reg_reg dest source 2++instance Mov Reg32 Reg32 where+  mov (Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_mov_reg_reg dest source 4+++instance Mov Reg32 Word32 where+  mov (Reg32 dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_mov_reg_imm dest (fromIntegral imm)++instance Mov Reg32 Label where+  mov (Reg32 dest) lab = do ensureBufferSize x86_max_instruction_bytes >> x86_mov_reg_imm dest 0+                            emitFixup lab (-4) Fixup32Absolute++instance Mov Addr Word8 where+  mov (Addr dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_mov_mem_imm dest (fromIntegral imm) 1++instance Mov Addr Word16 where+  mov (Addr dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_mov_mem_imm dest (fromIntegral imm) 2++instance Mov Addr Word32 where+  mov (Addr dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_mov_mem_imm dest imm 4++instance Mov Addr Label where+  mov (Addr dest) lab = do ensureBufferSize x86_max_instruction_bytes >> x86_mov_mem_imm dest 0 4+                           emitFixup lab (-4) Fixup32Absolute++instance Mov (Disp, Reg32) Word8 where+  mov (Disp disp, Reg32 dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_mov_membase_imm dest disp (fromIntegral imm) 1++instance Mov Ind Word8 where+  mov (Ind (Reg32 dest)) imm = ensureBufferSize x86_max_instruction_bytes >> x86_mov_membase_imm dest 0 (fromIntegral imm) 1++instance Mov (Disp, Reg32) Word16 where+  mov (Disp disp, Reg32 dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_mov_membase_imm dest disp (fromIntegral imm) 2++instance Mov Ind Word16 where+  mov (Ind (Reg32 dest)) imm = ensureBufferSize x86_max_instruction_bytes >> x86_mov_membase_imm dest 0 (fromIntegral imm) 2++instance Mov (Disp, Reg32) Word32 where+  mov (Disp disp, Reg32 dest) imm = ensureBufferSize x86_max_instruction_bytes >> x86_mov_membase_imm dest disp imm 4++instance Mov (Disp, Reg32) Label where+  mov (Disp disp, Reg32 dest) lab = do ensureBufferSize x86_max_instruction_bytes >> x86_mov_membase_imm dest disp 0 4+                                       emitFixup lab (-4) Fixup32Absolute++instance Mov Ind Word32 where+  mov (Ind (Reg32 dest)) imm = ensureBufferSize x86_max_instruction_bytes >> x86_mov_membase_imm dest 0 imm 4++instance Mov Ind Label where+  mov (Ind (Reg32 dest)) lab = do ensureBufferSize x86_max_instruction_bytes >> x86_mov_membase_imm dest 0 0 4+                                  emitFixup lab (-4) Fixup32Absolute++instance Mov (Reg32, Reg32, Scale) Word8 where+  mov (Reg32 base, Reg32 index, scale) imm = ensureBufferSize x86_max_instruction_bytes >> x86_mov_memindex_imm base 0 index (scaleToShift scale) (fromIntegral imm) 1++instance Mov (Reg32, Reg32, Scale) Word16 where+  mov (Reg32 base, Reg32 index, scale) imm = ensureBufferSize x86_max_instruction_bytes >> x86_mov_memindex_imm base 0 index (scaleToShift scale) (fromIntegral imm) 2++instance Mov (Reg32, Reg32, Scale) Word32 where+  mov (Reg32 base, Reg32 index, scale) imm = ensureBufferSize x86_max_instruction_bytes >> x86_mov_memindex_imm base 0 index (scaleToShift scale) imm 4++instance Mov (Reg32, Reg32, Scale) Label where+  mov (Reg32 base, Reg32 index, scale) lab = do ensureBufferSize x86_max_instruction_bytes >> x86_mov_memindex_imm base 0 index (scaleToShift scale) 0 4+                                                emitFixup lab (-4) Fixup32Absolute++instance Mov (Disp, Reg32, Scale) Word8 where+  mov (Disp disp, Reg32 index, scale) imm = ensureBufferSize x86_max_instruction_bytes >> x86_mov_memindex_imm x86_nobasereg disp index (scaleToShift scale) (fromIntegral imm) 1++instance Mov (Disp, Reg32, Scale) Word16 where+  mov (Disp disp, Reg32 index, scale) imm = ensureBufferSize x86_max_instruction_bytes >> x86_mov_memindex_imm x86_nobasereg disp index (scaleToShift scale) (fromIntegral imm) 2++instance Mov (Disp, Reg32, Scale) Word32 where+  mov (Disp disp, Reg32 index, scale) imm = ensureBufferSize x86_max_instruction_bytes >> x86_mov_memindex_imm x86_nobasereg disp index (scaleToShift scale) imm 4++instance Mov (Disp, Reg32, Scale) Label where+  mov (Disp disp, Reg32 index, scale) lab = do ensureBufferSize x86_max_instruction_bytes >> x86_mov_memindex_imm x86_nobasereg disp index (scaleToShift scale) 0 4+                                               emitFixup lab (-4) Fixup32Absolute++instance Mov (Disp, Reg32, Reg32, Scale) Word8 where+  mov (Disp disp, Reg32 5, Reg32 index, scale) imm = ensureBufferSize x86_max_instruction_bytes >> x86_mov_memindex_imm 5 disp index (scaleToShift scale) (fromIntegral imm) 1+  mov _ _ = onlyEbp++instance Mov (Disp, Reg32, Reg32, Scale) Word16 where+  mov (Disp disp, Reg32 5, Reg32 index, scale) imm = ensureBufferSize x86_max_instruction_bytes >> x86_mov_memindex_imm 5 disp index (scaleToShift scale) (fromIntegral imm) 2+  mov _ _ = onlyEbp++instance Mov (Disp, Reg32, Reg32, Scale) Word32 where+  mov (Disp disp, Reg32 5, Reg32 index, scale) imm = ensureBufferSize x86_max_instruction_bytes >> x86_mov_memindex_imm 5 disp index (scaleToShift scale) imm 4+  mov _ _ = onlyEbp++instance Mov (Disp, Reg32, Reg32, Scale) Label where+  mov (Disp disp, Reg32 5, Reg32 index, scale) lab = do ensureBufferSize x86_max_instruction_bytes >> x86_mov_memindex_imm 5 disp index (scaleToShift scale) 0 4+                                                        emitFixup lab (-4) Fixup32Absolute+  mov _ _ = onlyEbp++instance Mov Addr Reg8 where+  mov (Addr a) (Reg8 source) = ensureBufferSize x86_max_instruction_bytes >> x86_mov_mem_reg a source 1++instance Mov Addr Reg16 where+  mov (Addr a) (Reg16 source) = ensureBufferSize x86_max_instruction_bytes >> x86_mov_mem_reg a source 2++instance Mov Addr Reg32 where+  mov (Addr a) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_mov_mem_reg a source 4++instance Mov Reg8 Addr where+  mov (Reg8 dest) (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_mov_reg_mem dest a 1++instance Mov Reg16 Addr where+  mov (Reg16 dest) (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_mov_reg_mem dest a 2++instance Mov Reg32 Addr where+  mov (Reg32 dest) (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_mov_reg_mem dest a 4+++instance Mov Ind Reg8 where+  mov (Ind (Reg32 dest)) (Reg8 source) = ensureBufferSize x86_max_instruction_bytes >> x86_mov_regp_reg dest source 1++instance Mov Ind Reg16 where+  mov (Ind (Reg32 dest)) (Reg16 source) = ensureBufferSize x86_max_instruction_bytes >> x86_mov_regp_reg dest source 2++instance Mov Ind Reg32 where+  mov (Ind (Reg32 dest)) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_mov_regp_reg dest source 4++instance Mov Reg8 Ind where+  mov (Reg8 dest) (Ind (Reg32 source)) = ensureBufferSize x86_max_instruction_bytes >> x86_mov_reg_regp dest source 1++instance Mov Reg16 Ind where+  mov (Reg16 dest) (Ind (Reg32 source)) = ensureBufferSize x86_max_instruction_bytes >> x86_mov_reg_regp dest source 2++instance Mov Reg32 Ind where+  mov (Reg32 dest) (Ind (Reg32 source)) = ensureBufferSize x86_max_instruction_bytes >> x86_mov_reg_regp dest source 4+++instance Mov (Disp, Reg32) Reg8 where+  mov (Disp disp, Reg32 dest) (Reg8 source) = ensureBufferSize x86_max_instruction_bytes >> x86_mov_membase_reg dest disp source 1++instance Mov (Disp, Reg32) Reg16 where+  mov (Disp disp, Reg32 dest) (Reg16 source) = ensureBufferSize x86_max_instruction_bytes >> x86_mov_membase_reg dest disp source 2++instance Mov (Disp, Reg32) Reg32 where+  mov (Disp disp, Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_mov_membase_reg dest disp source 4++instance Mov Reg8 (Disp, Reg32) where+  mov (Reg8 dest) (Disp disp, Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_mov_reg_membase dest source disp 1++instance Mov Reg16 (Disp, Reg32) where+  mov (Reg16 dest) (Disp disp, Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_mov_reg_membase dest source disp 2++instance Mov Reg32 (Disp, Reg32) where+  mov (Reg32 dest) (Disp disp, Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_mov_reg_membase dest source disp 4+++instance Mov (Reg32, Reg32, Scale) Reg8 where+  mov (Reg32 base, Reg32 index, s) (Reg8 source) = ensureBufferSize x86_max_instruction_bytes >> x86_mov_memindex_reg base 0 index (scaleToShift s) source 1++instance Mov (Reg32, Reg32, Scale) Reg16 where+  mov (Reg32 base, Reg32 index, s) (Reg16 source) = ensureBufferSize x86_max_instruction_bytes >> x86_mov_memindex_reg base 0 index (scaleToShift s) source 2++instance Mov (Reg32, Reg32, Scale) Reg32 where+  mov (Reg32 base, Reg32 index, s) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_mov_memindex_reg base 0 index (scaleToShift s) source 4++instance Mov Reg8 (Reg32, Reg32, Scale) where+  mov (Reg8 dest) (Reg32 base, Reg32 index, s) = ensureBufferSize x86_max_instruction_bytes >> x86_mov_reg_memindex dest base 0 index (scaleToShift s) 1++instance Mov Reg16 (Reg32, Reg32, Scale) where+  mov (Reg16 dest) (Reg32 base, Reg32 index, s) = ensureBufferSize x86_max_instruction_bytes >> x86_mov_reg_memindex dest base 0 index (scaleToShift s) 2++instance Mov Reg32 (Reg32, Reg32, Scale) where+  mov (Reg32 dest) (Reg32 base, Reg32 index, s) = ensureBufferSize x86_max_instruction_bytes >> x86_mov_reg_memindex dest base 0 index (scaleToShift s) 4+++instance Mov (Disp, Reg32, Scale) Reg8 where+  mov (Disp disp, Reg32 index, s) (Reg8 source) = ensureBufferSize x86_max_instruction_bytes >> x86_mov_memindex_reg x86_nobasereg disp index (scaleToShift s) source 1++instance Mov (Disp, Reg32, Scale) Reg16 where+  mov (Disp disp, Reg32 index, s) (Reg16 source) = ensureBufferSize x86_max_instruction_bytes >> x86_mov_memindex_reg x86_nobasereg disp index (scaleToShift s) source 2++instance Mov (Disp, Reg32, Scale) Reg32 where+  mov (Disp disp, Reg32 index, s) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_mov_memindex_reg x86_nobasereg disp index (scaleToShift s) source 4++instance Mov Reg8 (Disp, Reg32, Scale) where+  mov (Reg8 dest) (Disp disp, Reg32 index, s) = ensureBufferSize x86_max_instruction_bytes >> x86_mov_reg_memindex dest x86_nobasereg disp index (scaleToShift s) 1++instance Mov Reg16 (Disp, Reg32, Scale) where+  mov (Reg16 dest) (Disp disp, Reg32 index, s) = ensureBufferSize x86_max_instruction_bytes >> x86_mov_reg_memindex dest x86_nobasereg disp index (scaleToShift s) 2++instance Mov Reg32 (Disp, Reg32, Scale) where+  mov (Reg32 dest) (Disp disp, Reg32 index, s) = ensureBufferSize x86_max_instruction_bytes >> x86_mov_reg_memindex dest x86_nobasereg disp index (scaleToShift s) 4+++instance Mov (Disp, Reg32, Reg32, Scale) Reg8 where+  mov (Disp disp, Reg32 5, Reg32 index, s) (Reg8 source) = ensureBufferSize x86_max_instruction_bytes >> x86_mov_memindex_reg 5 disp index (scaleToShift s) source 1+  mov _ _ = onlyEbp++instance Mov (Disp, Reg32, Reg32, Scale) Reg16 where+  mov (Disp disp, Reg32 5, Reg32 index, s) (Reg16 source) = ensureBufferSize x86_max_instruction_bytes >> x86_mov_memindex_reg 5 disp index (scaleToShift s) source 2+  mov _ _ = onlyEbp++instance Mov (Disp, Reg32, Reg32, Scale) Reg32 where+  mov (Disp disp, Reg32 5, Reg32 index, s) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> ensureBufferSize x86_max_instruction_bytes >> x86_mov_memindex_reg 5 disp index (scaleToShift s) source 4+  mov _ _ = onlyEbp++instance Mov Reg8 (Disp, Reg32, Reg32, Scale) where+  mov (Reg8 dest) (Disp disp, Reg32 5, Reg32 index, s) = ensureBufferSize x86_max_instruction_bytes >> x86_mov_reg_memindex dest 5 disp index (scaleToShift s) 1+  mov _ _ = onlyEbp++instance Mov Reg16 (Disp, Reg32, Reg32, Scale) where+  mov (Reg16 dest) (Disp disp, Reg32 5, Reg32 index, s) = ensureBufferSize x86_max_instruction_bytes >> x86_mov_reg_memindex dest 5 disp index (scaleToShift s) 2+  mov _ _ = onlyEbp++instance Mov Reg32 (Disp, Reg32, Reg32, Scale) where+  mov (Reg32 dest) (Disp disp, Reg32 5, Reg32 index, s) = ensureBufferSize x86_max_instruction_bytes >> x86_mov_reg_memindex dest 5 disp index (scaleToShift s) 4+  mov _ _ = onlyEbp+++-- move with sign-extension++class Movsxb a b where+  movsxb :: a -> b -> CodeGen e s ()++instance Movsxb Reg32 Reg8 where+  movsxb (Reg32 dest) (Reg8 source) = ensureBufferSize x86_max_instruction_bytes >> x86_widen_reg dest source True False++instance Movsxb Reg32 Addr where+  movsxb (Reg32 dest) (Addr source) = ensureBufferSize x86_max_instruction_bytes >> x86_widen_mem dest source True False++instance Movsxb Reg32 (Disp, Reg32) where+  movsxb (Reg32 dest) (Disp disp, Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_widen_membase dest source disp True False++instance Movsxb Reg32 Ind where+  movsxb (Reg32 dest) (Ind (Reg32 source)) = ensureBufferSize x86_max_instruction_bytes >> x86_widen_membase dest source 0 True False++instance Movsxb Reg32 (Disp, Reg32, Reg32, Scale) where+  movsxb (Reg32 dest) (Disp disp, Reg32 5, Reg32 index, s) = ensureBufferSize x86_max_instruction_bytes >> x86_widen_memindex dest 5 disp index (scaleToShift s) True False+  movsxb _ _ = onlyEbp++instance Movsxb Reg32 (Disp, Reg32, Scale) where+  movsxb (Reg32 dest) (Disp disp, Reg32 index, s) = ensureBufferSize x86_max_instruction_bytes >> x86_widen_memindex dest x86_nobasereg disp index (scaleToShift s) True False++instance Movsxb Reg32 (Reg32, Reg32, Scale) where+  movsxb (Reg32 dest) (Reg32 base, Reg32 index, s) = ensureBufferSize x86_max_instruction_bytes >> x86_widen_memindex dest base 0 index (scaleToShift s) True False++class Movsxw a b where+  movsxw :: a -> b -> CodeGen e s ()++instance Movsxw Reg32 Reg16 where+  movsxw (Reg32 dest) (Reg16 source) = ensureBufferSize x86_max_instruction_bytes >> x86_widen_reg dest source True True++instance Movsxw Reg32 Addr where+  movsxw (Reg32 dest) (Addr source) = ensureBufferSize x86_max_instruction_bytes >> x86_widen_mem dest source True True++instance Movsxw Reg32 (Disp, Reg32) where+  movsxw (Reg32 dest) (Disp disp, Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_widen_membase dest source disp True True++instance Movsxw Reg32 Ind where+  movsxw (Reg32 dest) (Ind (Reg32 source)) = ensureBufferSize x86_max_instruction_bytes >> x86_widen_membase dest source 0 True True++instance Movsxw Reg32 (Disp, Reg32, Reg32, Scale) where+  movsxw (Reg32 dest) (Disp disp, Reg32 5, Reg32 index, s) = ensureBufferSize x86_max_instruction_bytes >> x86_widen_memindex dest 5 disp index (scaleToShift s) True True+  movsxw _ _ = onlyEbp++instance Movsxw Reg32 (Disp, Reg32, Scale) where+  movsxw (Reg32 dest) (Disp disp, Reg32 index, s) = ensureBufferSize x86_max_instruction_bytes >> x86_widen_memindex dest x86_nobasereg disp index (scaleToShift s) True True++instance Movsxw Reg32 (Reg32, Reg32, Scale) where+  movsxw (Reg32 dest) (Reg32 base, Reg32 index, s) = ensureBufferSize x86_max_instruction_bytes >> x86_widen_memindex dest base 0 index (scaleToShift s) True True+++-- move with zero-extension++class Movzxb a b where+  movzxb :: a -> b -> CodeGen e s ()++instance Movzxb Reg32 Reg8 where+  movzxb (Reg32 dest) (Reg8 source) = ensureBufferSize x86_max_instruction_bytes >> x86_widen_reg dest source False False++instance Movzxb Reg32 Addr where+  movzxb (Reg32 dest) (Addr source) = ensureBufferSize x86_max_instruction_bytes >> x86_widen_mem dest source False False++instance Movzxb Reg32 (Disp, Reg32) where+  movzxb (Reg32 dest) (Disp disp, Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_widen_membase dest source disp False False++instance Movzxb Reg32 Ind where+  movzxb (Reg32 dest) (Ind (Reg32 source)) = ensureBufferSize x86_max_instruction_bytes >> x86_widen_membase dest source 0 False False++instance Movzxb Reg32 (Disp, Reg32, Reg32, Scale) where+  movzxb (Reg32 dest) (Disp disp, Reg32 5, Reg32 index, s) = ensureBufferSize x86_max_instruction_bytes >> x86_widen_memindex dest 5 disp index (scaleToShift s) False False+  movzxb _ _ = onlyEbp++instance Movzxb Reg32 (Disp, Reg32, Scale) where+  movzxb (Reg32 dest) (Disp disp, Reg32 index, s) = ensureBufferSize x86_max_instruction_bytes >> x86_widen_memindex dest x86_nobasereg disp index (scaleToShift s) False False++instance Movzxb Reg32 (Reg32, Reg32, Scale) where+  movzxb (Reg32 dest) (Reg32 base, Reg32 index, s) = ensureBufferSize x86_max_instruction_bytes >> x86_widen_memindex dest base 0 index (scaleToShift s) False False++class Movzxw a b where+  movzxw :: a -> b -> CodeGen e s ()++instance Movzxw Reg32 Reg16 where+  movzxw (Reg32 dest) (Reg16 source) = ensureBufferSize x86_max_instruction_bytes >> x86_widen_reg dest source False True++instance Movzxw Reg32 Addr where+  movzxw (Reg32 dest) (Addr source) = ensureBufferSize x86_max_instruction_bytes >> x86_widen_mem dest source False True++instance Movzxw Reg32 (Disp, Reg32) where+  movzxw (Reg32 dest) (Disp disp, Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_widen_membase dest source disp False True++instance Movzxw Reg32 Ind where+  movzxw (Reg32 dest) (Ind (Reg32 source)) = ensureBufferSize x86_max_instruction_bytes >> x86_widen_membase dest source 0 False True++instance Movzxw Reg32 (Disp, Reg32, Reg32, Scale) where+  movzxw (Reg32 dest) (Disp disp, Reg32 5, Reg32 index, s) = ensureBufferSize x86_max_instruction_bytes >> x86_widen_memindex dest 5 disp index (scaleToShift s) False True+  movzxw _ _ = onlyEbp++instance Movzxw Reg32 (Disp, Reg32, Scale) where+  movzxw (Reg32 dest) (Disp disp, Reg32 index, s) = ensureBufferSize x86_max_instruction_bytes >> x86_widen_memindex dest x86_nobasereg disp index (scaleToShift s) False True++instance Movzxw Reg32 (Reg32, Reg32, Scale) where+  movzxw (Reg32 dest) (Reg32 base, Reg32 index, s) = ensureBufferSize x86_max_instruction_bytes >> x86_widen_memindex dest base 0 index (scaleToShift s) False True+++-- load effective address++class Lea a b where+  lea :: a -> b -> CodeGen e s ()++instance Lea Reg32 Addr where+  lea (Reg32 dest) (Addr source) = ensureBufferSize x86_max_instruction_bytes >> x86_lea_mem dest source ++instance Lea Reg32 (Disp, Reg32) where+  lea (Reg32 dest) (Disp disp, Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_lea_membase dest source disp ++instance Lea Reg32 Ind where+  lea (Reg32 dest) (Ind (Reg32 source)) = ensureBufferSize x86_max_instruction_bytes >> x86_lea_membase dest source 0 ++instance Lea Reg32 (Disp, Reg32, Reg32, Scale) where+  lea (Reg32 dest) (Disp disp, Reg32 5, Reg32 index, s) = ensureBufferSize x86_max_instruction_bytes >> x86_lea_memindex dest 5 disp index (scaleToShift s)+  lea _ _ = onlyEbp++instance Lea Reg32 (Disp, Reg32, Scale) where+  lea (Reg32 dest) (Disp disp, Reg32 index, s) = ensureBufferSize x86_max_instruction_bytes >> x86_lea_memindex dest x86_nobasereg disp index (scaleToShift s)++instance Lea Reg32 (Reg32, Reg32, Scale) where+  lea (Reg32 dest) (Reg32 base, Reg32 index, s) = ensureBufferSize x86_max_instruction_bytes >> x86_lea_memindex dest base 0 index (scaleToShift s)+++-- convert word to doubleword++cdq = ensureBufferSize x86_max_instruction_bytes >> x86_cdq+++-- wait for FPU++wait = ensureBufferSize x86_max_instruction_bytes >> x86_wait+++-- push to stack++class Push a where+  push :: a -> CodeGen e s ()++instance Push Reg32 where+  push (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_push_reg source ++instance Push Ind where+  push (Ind (Reg32 source)) = ensureBufferSize x86_max_instruction_bytes >> x86_push_regp source++instance Push Addr where+  push (Addr source) = ensureBufferSize x86_max_instruction_bytes >> x86_push_mem source ++instance Push (Disp, Reg32) where+  push (Disp disp, Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_push_membase source disp ++instance Push Word32 where+  push imm = ensureBufferSize x86_max_instruction_bytes >> x86_push_imm imm ++instance Push Label where+  push l = do ensureBufferSize x86_max_instruction_bytes >> x86_push_imm_template+              emitFixup l (-4) Fixup32Absolute++instance Push (Disp, Reg32, Reg32, Scale) where+  push (Disp disp, Reg32 5, Reg32 index, s) = ensureBufferSize x86_max_instruction_bytes >> x86_push_memindex 5 disp index (scaleToShift s)+  push _ = onlyEbp++instance Push (Disp, Reg32, Scale) where+  push (Disp disp, Reg32 index, s) = ensureBufferSize x86_max_instruction_bytes >> x86_push_memindex x86_nobasereg disp index (scaleToShift s)++instance Push (Reg32, Reg32, Scale) where+  push (Reg32 base, Reg32 index, s) = ensureBufferSize x86_max_instruction_bytes >> x86_push_memindex base 0 index (scaleToShift s)+++-- pop from stack++class Pop a where+  pop :: a -> CodeGen e s ()++instance Pop Reg32 where+  pop (Reg32 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_pop_reg dest ++instance Pop Addr where+  pop (Addr dest) = ensureBufferSize x86_max_instruction_bytes >> x86_pop_mem dest ++instance Pop (Disp, Reg32) where+  pop (Disp disp, Reg32 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_pop_membase dest disp ++instance Pop Ind where+  pop (Ind (Reg32 dest)) = ensureBufferSize x86_max_instruction_bytes >> x86_pop_membase dest 0 +++-- push/pop general purpose registers++pushad = ensureBufferSize x86_max_instruction_bytes >> x86_pushad+popad  = ensureBufferSize x86_max_instruction_bytes >> x86_popad+++-- push/pop EFLAGS++pushfd = ensureBufferSize x86_max_instruction_bytes >> x86_pushfd+popfd  = ensureBufferSize x86_max_instruction_bytes >> x86_popfd+++-- loop according to ECX couter++loop   :: Word8 -> CodeGen e s ()+loop w   = ensureBufferSize x86_max_instruction_bytes >> x86_loop w++loope  :: Word8 -> CodeGen e s ()+loope w  = ensureBufferSize x86_max_instruction_bytes >> x86_loope w++loopne :: Word8 -> CodeGen e s ()+loopne w = ensureBufferSize x86_max_instruction_bytes >> x86_loopne w+++-- jump++class Jmp a where+  jmp :: a -> CodeGen e s ()++instance Jmp Word8 where+  jmp imm = ensureBufferSize x86_max_instruction_bytes >> x86_jump8 imm ++instance Jmp Word32 where+  jmp imm = ensureBufferSize x86_max_instruction_bytes >> x86_jump32 imm ++instance Jmp Reg32 where+  jmp (Reg32 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_jump_reg dest ++instance Jmp Addr where+  jmp (Addr dest) = ensureBufferSize x86_max_instruction_bytes >> x86_jump_mem dest ++instance Jmp (Disp, Reg32) where+  jmp (Disp disp, Reg32 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_jump_membase dest disp ++instance Jmp Ind where+  jmp (Ind (Reg32 dest)) = ensureBufferSize x86_max_instruction_bytes >> x86_jump_membase dest 0 ++instance Jmp Label where+  jmp l = do ensureBufferSize x86_max_instruction_bytes >> x86_jump32 0+             emitFixup l (-4) Fixup32+            +-- jump on condition code (branch)++class Ja a where+  ja :: a -> CodeGen e s ()++instance Ja Word8 where+  ja imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch8 x86_cc_a imm False++instance Ja Word32 where+  ja imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_a imm False++instance Ja Label where+  ja l = do ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_a 0 False+            emitFixup l (-4) Fixup32++class Jae a where+  jae :: a -> CodeGen e s ()++instance Jae Word8 where+  jae imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch8 x86_cc_ae imm False++instance Jae Word32 where+  jae imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_ae imm False++instance Jae Label where+  jae l = do ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_ae 0 False+             emitFixup l (-4) Fixup32++class Jb a where+  jb :: a -> CodeGen e s ()++instance Jb Word8 where+  jb imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch8 x86_cc_b imm False++instance Jb Word32 where+  jb imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_b imm False++instance Jb Label where+  jb l = do ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_b 0 False+            emitFixup l (-4) Fixup32++class Jbe a where+  jbe :: a -> CodeGen e s ()++instance Jbe Word8 where+  jbe imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch8 x86_cc_be imm False++instance Jbe Word32 where+  jbe imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_be imm False++instance Jbe Label where+  jbe l = do ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_be 0 False+             emitFixup l (-4) Fixup32++class Jc a where+  jc :: a -> CodeGen e s ()++instance Jc Word8 where+  jc imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch8 x86_cc_c imm False++instance Jc Word32 where+  jc imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_c imm False++instance Jc Label where+  jc l = do ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_c 0 False+            emitFixup l (-4) Fixup32++class Je a where+  je :: a -> CodeGen e s ()++instance Je Word8 where+  je imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch8 x86_cc_e imm False++instance Je Word32 where+  je imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_e imm False++instance Je Label where+  je l = do ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_e 0 False+            emitFixup l (-4) Fixup32++class Jna a where+  jna :: a -> CodeGen e s ()++instance Jna Word8 where+  jna imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch8 x86_cc_na imm False++instance Jna Word32 where+  jna imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_na imm False++instance Jna Label where+  jna l = do ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_na 0 False+             emitFixup l (-4) Fixup32++class Jnae a where+  jnae :: a -> CodeGen e s ()++instance Jnae Word8 where+  jnae imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch8 x86_cc_nae imm False++instance Jnae Word32 where+  jnae imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_nae imm False++instance Jnae Label where+  jnae l = do ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_nae 0 False+              emitFixup l (-4) Fixup32++class Jnb a where+  jnb :: a -> CodeGen e s ()++instance Jnb Word8 where+  jnb imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch8 x86_cc_nb imm False++instance Jnb Word32 where+  jnb imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_nb imm False++instance Jnb Label where+  jnb l = do ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_nb 0 False+             emitFixup l (-4) Fixup32++class Jnbe a where+  jnbe :: a -> CodeGen e s ()++instance Jnbe Word8 where+  jnbe imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch8 x86_cc_nbe imm False++instance Jnbe Word32 where+  jnbe imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_nbe imm False++instance Jnbe Label where+  jnbe l = do ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_nbe 0 False+              emitFixup l (-4) Fixup32++class Jnc a where+  jnc :: a -> CodeGen e s ()++instance Jnc Word8 where+  jnc imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch8 x86_cc_nc imm False++instance Jnc Word32 where+  jnc imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_nc imm False++instance Jnc Label where+  jnc l = do ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_nc 0 False+             emitFixup l (-4) Fixup32++class Jne a where+  jne :: a -> CodeGen e s ()++instance Jne Word8 where+  jne imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch8 x86_cc_ne imm False++instance Jne Word32 where+  jne imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_ne imm False++instance Jne Label where+  jne l = do ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_ne 0 False+             emitFixup l (-4) Fixup32++class Jnp a where+  jnp :: a -> CodeGen e s ()++instance Jnp Word8 where+  jnp imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch8 x86_cc_np imm False++instance Jnp Word32 where+  jnp imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_np imm False++instance Jnp Label where+  jnp l = do ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_np 0 False+             emitFixup l (-4) Fixup32++class Jnz a where+  jnz :: a -> CodeGen e s ()++instance Jnz Word8 where+  jnz imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch8 x86_cc_nz imm False++instance Jnz Word32 where+  jnz imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_nz imm False++instance Jnz Label where+  jnz l = do ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_nz 0 False+             emitFixup l (-4) Fixup32++class Jp a where+  jp :: a -> CodeGen e s ()++instance Jp Word8 where+  jp imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch8 x86_cc_p imm False++instance Jp Word32 where+  jp imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_p imm False++instance Jp Label where+  jp l = do ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_p 0 False+            emitFixup l (-4) Fixup32++class Jpe a where+  jpe :: a -> CodeGen e s ()++instance Jpe Word8 where+  jpe imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch8 x86_cc_pe imm False++instance Jpe Word32 where+  jpe imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_pe imm False++instance Jpe Label where+  jpe l = do ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_pe 0 False+             emitFixup l (-4) Fixup32++class Jpo a where+  jpo :: a -> CodeGen e s ()++instance Jpo Word8 where+  jpo imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch8 x86_cc_po imm False++instance Jpo Word32 where+  jpo imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_po imm False++instance Jpo Label where+  jpo l = do ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_po 0 False+             emitFixup l (-4) Fixup32++class Jz a where+  jz :: a -> CodeGen e s ()++instance Jz Word8 where+  jz imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch8 x86_cc_z imm False++instance Jz Word32 where+  jz imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_z imm False++instance Jz Label where+  jz l = do ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_z 0 False+            emitFixup l (-4) Fixup32++class Jg a where+  jg :: a -> CodeGen e s ()++instance Jg Word8 where+  jg imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch8 x86_cc_gt imm True++instance Jg Word32 where+  jg imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_gt imm True++instance Jg Label where+  jg l = do ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_gt 0 True+            emitFixup l (-4) Fixup32++class Jge a where+  jge :: a -> CodeGen e s ()++instance Jge Word8 where+  jge imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch8 x86_cc_ge imm True++instance Jge Word32 where+  jge imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_ge imm True++instance Jge Label where+  jge l = do ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_ge 0 True+             emitFixup l (-4) Fixup32++class Jl a where+  jl :: a -> CodeGen e s ()++instance Jl Word8 where+  jl imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch8 x86_cc_lt imm True++instance Jl Word32 where+  jl imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_lt imm True++instance Jl Label where+  jl l = do ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_lt 0 True+            emitFixup l (-4) Fixup32++class Jle a where+  jle :: a -> CodeGen e s ()++instance Jle Word8 where+  jle imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch8 x86_cc_le imm True++instance Jle Word32 where+  jle imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_le imm True++instance Jle Label where+  jle l = do ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_le 0 True+             emitFixup l (-4) Fixup32++class Jng a where+  jng :: a -> CodeGen e s ()++instance Jng Word8 where+  jng imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch8 x86_cc_le imm True++instance Jng Word32 where+  jng imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_le imm True++instance Jng Label where+  jng l = do ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_le 0 True+             emitFixup l (-4) Fixup32++class Jnge a where+  jnge :: a -> CodeGen e s ()++instance Jnge Word8 where+  jnge imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch8 x86_cc_lt imm True++instance Jnge Word32 where+  jnge imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_lt imm True++instance Jnge Label where+  jnge l = do ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_lt 0 True+              emitFixup l (-4) Fixup32++class Jnl a where+  jnl :: a -> CodeGen e s ()++instance Jnl Word8 where+  jnl imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch8 x86_cc_ge imm True++instance Jnl Word32 where+  jnl imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_ge imm True++instance Jnl Label where+  jnl l = do ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_ge 0 True+             emitFixup l (-4) Fixup32++class Jnle a where+  jnle :: a -> CodeGen e s ()++instance Jnle Word8 where+  jnle imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch8 x86_cc_gt imm True++instance Jnle Word32 where+  jnle imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_gt imm True++instance Jnle Label where+  jnle l = do ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_gt 0 True+              emitFixup l (-4) Fixup32++class Jno a where+  jno :: a -> CodeGen e s ()++instance Jno Word8 where+  jno imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch8 x86_cc_no imm True++instance Jno Word32 where+  jno imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_no imm True++instance Jno Label where+  jno l = do ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_no 0 True+             emitFixup l (-4) Fixup32++class Jns a where+  jns :: a -> CodeGen e s ()++instance Jns Word8 where+  jns imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch8 x86_cc_ns imm True++instance Jns Word32 where+  jns imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_ns imm True++instance Jns Label where+  jns l = do ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_ns 0 True+             emitFixup l (-4) Fixup32++class Jo a where+  jo :: a -> CodeGen e s ()++instance Jo Word8 where+  jo imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch8 x86_cc_o imm True++instance Jo Word32 where+  jo imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_o imm True++instance Jo Label where+  jo l = do ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_o 0 True+            emitFixup l (-4) Fixup32++class Js a where+  js :: a -> CodeGen e s ()++instance Js Word8 where+  js imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch8 x86_cc_s imm True++instance Js Word32 where+  js imm = ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_s imm True++instance Js Label where+  js l = do ensureBufferSize x86_max_instruction_bytes >> x86_branch32 x86_cc_s 0 True+            emitFixup l (-4) Fixup32++-- jump if ecx register is 0++jecxz :: Word8 -> CodeGen e s ()+jecxz w = ensureBufferSize x86_max_instruction_bytes >> x86_jecxz w+++-- set byte on condition code++class Seta a where+  seta :: a -> CodeGen e s ()++instance Seta Reg8 where+  seta (Reg8 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_reg x86_cc_a dest False++instance Seta Addr where+  seta (Addr dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_mem x86_cc_a dest False++instance Seta (Disp, Reg32) where+  seta (Disp disp, Reg32 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_a dest disp False++instance Seta Ind where+  seta (Ind (Reg32 dest)) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_a dest 0 False++class Setae a where+  setae :: a -> CodeGen e s ()++instance Setae Reg8 where+  setae (Reg8 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_reg x86_cc_ae dest False++instance Setae Addr where+  setae (Addr dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_mem x86_cc_ae dest False++instance Setae (Disp, Reg32) where+  setae (Disp disp, Reg32 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_ae dest disp False++instance Setae Ind where+  setae (Ind (Reg32 dest)) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_ae dest 0 False++class Setb a where+  setb :: a -> CodeGen e s ()++instance Setb Reg8 where+  setb (Reg8 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_reg x86_cc_b dest False++instance Setb Addr where+  setb (Addr dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_mem x86_cc_b dest False++instance Setb (Disp, Reg32) where+  setb (Disp disp, Reg32 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_b dest disp False++instance Setb Ind where+  setb (Ind (Reg32 dest)) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_b dest 0 False++class Setbe a where+  setbe :: a -> CodeGen e s ()++instance Setbe Reg8 where+  setbe (Reg8 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_reg x86_cc_be dest False++instance Setbe Addr where+  setbe (Addr dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_mem x86_cc_be dest False++instance Setbe (Disp, Reg32) where+  setbe (Disp disp, Reg32 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_be dest disp False++instance Setbe Ind where+  setbe (Ind (Reg32 dest)) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_be dest 0 False++class Setc a where+  setc :: a -> CodeGen e s ()++instance Setc Reg8 where+  setc (Reg8 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_reg x86_cc_c dest False++instance Setc Addr where+  setc (Addr dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_mem x86_cc_c dest False++instance Setc (Disp, Reg32) where+  setc (Disp disp, Reg32 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_c dest disp False++instance Setc Ind where+  setc (Ind (Reg32 dest)) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_c dest 0 False++class Sete a where+  sete :: a -> CodeGen e s ()++instance Sete Reg8 where+  sete (Reg8 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_reg x86_cc_e dest False++instance Sete Addr where+  sete (Addr dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_mem x86_cc_e dest False++instance Sete (Disp, Reg32) where+  sete (Disp disp, Reg32 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_e dest disp False++instance Sete Ind where+  sete (Ind (Reg32 dest)) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_e dest 0 False++class Setna a where+  setna :: a -> CodeGen e s ()++instance Setna Reg8 where+  setna (Reg8 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_reg x86_cc_na dest False++instance Setna Addr where+  setna (Addr dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_mem x86_cc_na dest False++instance Setna (Disp, Reg32) where+  setna (Disp disp, Reg32 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_na dest disp False++instance Setna Ind where+  setna (Ind (Reg32 dest)) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_na dest 0 False++class Setnae a where+  setnae :: a -> CodeGen e s ()++instance Setnae Reg8 where+  setnae (Reg8 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_reg x86_cc_nae dest False++instance Setnae Addr where+  setnae (Addr dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_mem x86_cc_nae dest False++instance Setnae (Disp, Reg32) where+  setnae (Disp disp, Reg32 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_nae dest disp False++instance Setnae Ind where+  setnae (Ind (Reg32 dest)) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_nae dest 0 False++class Setnb a where+  setnb :: a -> CodeGen e s ()++instance Setnb Reg8 where+  setnb (Reg8 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_reg x86_cc_nb dest False++instance Setnb Addr where+  setnb (Addr dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_mem x86_cc_nb dest False++instance Setnb (Disp, Reg32) where+  setnb (Disp disp, Reg32 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_nb dest disp False++instance Setnb Ind where+  setnb (Ind (Reg32 dest)) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_nb dest 0 False++class Setnbe a where+  setnbe :: a -> CodeGen e s ()++instance Setnbe Reg8 where+  setnbe (Reg8 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_reg x86_cc_nbe dest False++instance Setnbe Addr where+  setnbe (Addr dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_mem x86_cc_nbe dest False++instance Setnbe (Disp, Reg32) where+  setnbe (Disp disp, Reg32 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_nbe dest disp False++instance Setnbe Ind where+  setnbe (Ind (Reg32 dest)) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_nbe dest 0 False++class Setnc a where+  setnc :: a -> CodeGen e s ()++instance Setnc Reg8 where+  setnc (Reg8 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_reg x86_cc_nc dest False++instance Setnc Addr where+  setnc (Addr dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_mem x86_cc_nc dest False++instance Setnc (Disp, Reg32) where+  setnc (Disp disp, Reg32 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_nc dest disp False++instance Setnc Ind where+  setnc (Ind (Reg32 dest)) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_nc dest 0 False++class Setne a where+  setne :: a -> CodeGen e s ()++instance Setne Reg8 where+  setne (Reg8 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_reg x86_cc_ne dest False++instance Setne Addr where+  setne (Addr dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_mem x86_cc_ne dest False++instance Setne (Disp, Reg32) where+  setne (Disp disp, Reg32 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_ne dest disp False++instance Setne Ind where+  setne (Ind (Reg32 dest)) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_ne dest 0 False++class Setnp a where+  setnp :: a -> CodeGen e s ()++instance Setnp Reg8 where+  setnp (Reg8 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_reg x86_cc_np dest False++instance Setnp Addr where+  setnp (Addr dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_mem x86_cc_np dest False++instance Setnp (Disp, Reg32) where+  setnp (Disp disp, Reg32 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_np dest disp False++instance Setnp Ind where+  setnp (Ind (Reg32 dest)) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_np dest 0 False++class Setnz a where+  setnz :: a -> CodeGen e s ()++instance Setnz Reg8 where+  setnz (Reg8 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_reg x86_cc_nz dest False++instance Setnz Addr where+  setnz (Addr dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_mem x86_cc_nz dest False++instance Setnz (Disp, Reg32) where+  setnz (Disp disp, Reg32 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_nz dest disp False++instance Setnz Ind where+  setnz (Ind (Reg32 dest)) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_nz dest 0 False++class Setp a where+  setp :: a -> CodeGen e s ()++instance Setp Reg8 where+  setp (Reg8 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_reg x86_cc_p dest False++instance Setp Addr where+  setp (Addr dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_mem x86_cc_p dest False++instance Setp (Disp, Reg32) where+  setp (Disp disp, Reg32 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_p dest disp False++instance Setp Ind where+  setp (Ind (Reg32 dest)) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_p dest 0 False++class Setpe a where+  setpe :: a -> CodeGen e s ()++instance Setpe Reg8 where+  setpe (Reg8 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_reg x86_cc_pe dest False++instance Setpe Addr where+  setpe (Addr dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_mem x86_cc_pe dest False++instance Setpe (Disp, Reg32) where+  setpe (Disp disp, Reg32 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_pe dest disp False++instance Setpe Ind where+  setpe (Ind (Reg32 dest)) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_pe dest 0 False++class Setpo a where+  setpo :: a -> CodeGen e s ()++instance Setpo Reg8 where+  setpo (Reg8 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_reg x86_cc_po dest False++instance Setpo Addr where+  setpo (Addr dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_mem x86_cc_po dest False++instance Setpo (Disp, Reg32) where+  setpo (Disp disp, Reg32 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_po dest disp False++instance Setpo Ind where+  setpo (Ind (Reg32 dest)) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_po dest 0 False++class Setg a where+  setg :: a -> CodeGen e s ()++instance Setg Reg8 where+  setg (Reg8 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_reg x86_cc_gt dest True++instance Setg Addr where+  setg (Addr dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_mem x86_cc_gt dest True++instance Setg (Disp, Reg32) where+  setg (Disp disp, Reg32 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_gt dest disp True++instance Setg Ind where+  setg (Ind (Reg32 dest)) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_gt dest 0 True++class Setge a where+  setge :: a -> CodeGen e s ()++instance Setge Reg8 where+  setge (Reg8 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_reg x86_cc_ge dest True++instance Setge Addr where+  setge (Addr dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_mem x86_cc_ge dest True++instance Setge (Disp, Reg32) where+  setge (Disp disp, Reg32 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_ge dest disp True++instance Setge Ind where+  setge (Ind (Reg32 dest)) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_ge dest 0 True++class Setl a where+  setl :: a -> CodeGen e s ()++instance Setl Reg8 where+  setl (Reg8 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_reg x86_cc_lt dest True++instance Setl Addr where+  setl (Addr dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_mem x86_cc_lt dest True++instance Setl (Disp, Reg32) where+  setl (Disp disp, Reg32 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_lt dest disp True++instance Setl Ind where+  setl (Ind (Reg32 dest)) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_lt dest 0 True++class Setle a where+  setle :: a -> CodeGen e s ()++instance Setle Reg8 where+  setle (Reg8 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_reg x86_cc_le dest True++instance Setle Addr where+  setle (Addr dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_mem x86_cc_le dest True++instance Setle (Disp, Reg32) where+  setle (Disp disp, Reg32 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_le dest disp True++instance Setle Ind where+  setle (Ind (Reg32 dest)) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_le dest 0 True++class Setng a where+  setng :: a -> CodeGen e s ()++instance Setng Reg8 where+  setng (Reg8 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_reg x86_cc_le dest True++instance Setng Addr where+  setng (Addr dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_mem x86_cc_le dest True++instance Setng (Disp, Reg32) where+  setng (Disp disp, Reg32 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_le dest disp True++instance Setng Ind where+  setng (Ind (Reg32 dest)) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_le dest 0 True++class Setnge a where+  setnge :: a -> CodeGen e s ()++instance Setnge Reg8 where+  setnge (Reg8 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_reg x86_cc_lt dest True++instance Setnge Addr where+  setnge (Addr dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_mem x86_cc_lt dest True++instance Setnge (Disp, Reg32) where+  setnge (Disp disp, Reg32 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_lt dest disp True++instance Setnge Ind where+  setnge (Ind (Reg32 dest)) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_lt dest 0 True++class Setnl a where+  setnl :: a -> CodeGen e s ()++instance Setnl Reg8 where+  setnl (Reg8 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_reg x86_cc_ge dest True++instance Setnl Addr where+  setnl (Addr dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_mem x86_cc_ge dest True++instance Setnl (Disp, Reg32) where+  setnl (Disp disp, Reg32 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_ge dest disp True++instance Setnl Ind where+  setnl (Ind (Reg32 dest)) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_ge dest 0 True++class Setnle a where+  setnle :: a -> CodeGen e s ()++instance Setnle Reg8 where+  setnle (Reg8 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_reg x86_cc_gt dest True++instance Setnle Addr where+  setnle (Addr dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_mem x86_cc_gt dest True++instance Setnle (Disp, Reg32) where+  setnle (Disp disp, Reg32 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_gt dest disp True++instance Setnle Ind where+  setnle (Ind (Reg32 dest)) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_gt dest 0 True++class Setno a where+  setno :: a -> CodeGen e s ()++instance Setno Reg8 where+  setno (Reg8 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_reg x86_cc_no dest True++instance Setno Addr where+  setno (Addr dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_mem x86_cc_no dest True++instance Setno (Disp, Reg32) where+  setno (Disp disp, Reg32 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_no dest disp True++instance Setno Ind where+  setno (Ind (Reg32 dest)) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_no dest 0 True++class Setns a where+  setns :: a -> CodeGen e s ()++instance Setns Reg8 where+  setns (Reg8 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_reg x86_cc_ns dest True++instance Setns Addr where+  setns (Addr dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_mem x86_cc_ns dest True++instance Setns (Disp, Reg32) where+  setns (Disp disp, Reg32 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_ns dest disp True++instance Setns Ind where+  setns (Ind (Reg32 dest)) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_ns dest 0 True++class Seto a where+  seto :: a -> CodeGen e s ()++instance Seto Reg8 where+  seto (Reg8 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_reg x86_cc_o dest True++instance Seto Addr where+  seto (Addr dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_mem x86_cc_o dest True++instance Seto (Disp, Reg32) where+  seto (Disp disp, Reg32 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_o dest disp True++instance Seto Ind where+  seto (Ind (Reg32 dest)) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_o dest 0 True++class Sets a where+  sets :: a -> CodeGen e s ()++instance Sets Reg8 where+  sets (Reg8 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_reg x86_cc_s dest True++instance Sets Addr where+  sets (Addr dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_mem x86_cc_s dest True++instance Sets (Disp, Reg32) where+  sets (Disp disp, Reg32 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_s dest disp True++instance Sets Ind where+  sets (Ind (Reg32 dest)) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_s dest 0 True++class Setz a where+  setz :: a -> CodeGen e s ()++instance Setz Reg8 where+  setz (Reg8 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_reg x86_cc_z dest False++instance Setz Addr where+  setz (Addr dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_mem x86_cc_z dest False++instance Setz (Disp, Reg32) where+  setz (Disp disp, Reg32 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_z dest disp False++instance Setz Ind where+  setz (Ind (Reg32 dest)) = ensureBufferSize x86_max_instruction_bytes >> x86_set_membase x86_cc_z dest 0 False+++-- call procedure++class Call a where+  call :: a -> CodeGen e s ()++instance Call Word32 where+  call imm = ensureBufferSize x86_max_instruction_bytes >> x86_call_imm imm ++instance Call Label where+  call l = do ensureBufferSize x86_max_instruction_bytes >> x86_call_imm 0+              emitFixup l (-4) Fixup32++instance Call Reg32 where+  call (Reg32 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_call_reg dest ++instance Call Addr where+  call (Addr dest) = ensureBufferSize x86_max_instruction_bytes >> x86_call_mem dest ++instance Call (Disp, Reg32) where+  call (Disp disp, Reg32 dest) = ensureBufferSize x86_max_instruction_bytes >> x86_call_membase dest disp ++instance Call Ind where+  call (Ind (Reg32 dest)) = ensureBufferSize x86_max_instruction_bytes >> x86_call_membase dest 0 ++instance Call (FunPtr a) where+  call f = ensureBufferSize x86_max_instruction_bytes >> x86_call_hs f+++-- return from procedure++ret :: CodeGen e s ()+ret = ensureBufferSize x86_max_instruction_bytes >> x86_ret++retN :: Word16 -> CodeGen e s ()+retN n = ensureBufferSize x86_max_instruction_bytes >> x86_ret_imm n+++-- make stack frame++enter :: Word16 -> CodeGen e s ()+enter w = ensureBufferSize x86_max_instruction_bytes >> x86_enter w+++-- conditional move++class Cmova a b where+  cmova :: a -> b -> CodeGen e s ()++instance Cmova Reg32 Reg32 where+  cmova (Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_reg x86_cc_a False dest source++instance Cmova Reg32 Addr where+  cmova (Reg32 dest) (Addr source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_mem x86_cc_a False dest source++instance Cmova Reg32 (Disp, Reg32) where+  cmova (Reg32 dest) (Disp disp, Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_a False dest source disp++instance Cmova Reg32 Ind where+  cmova (Reg32 dest) (Ind (Reg32 source)) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_a False dest source 0++class Cmovae a b where+  cmovae :: a -> b -> CodeGen e s ()++instance Cmovae Reg32 Reg32 where+  cmovae (Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_reg x86_cc_ae False dest source++instance Cmovae Reg32 Addr where+  cmovae (Reg32 dest) (Addr source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_mem x86_cc_ae False dest source++instance Cmovae Reg32 (Disp, Reg32) where+  cmovae (Reg32 dest) (Disp disp, Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_ae False dest source disp++instance Cmovae Reg32 Ind where+  cmovae (Reg32 dest) (Ind (Reg32 source)) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_ae False dest source 0++class Cmovb a b where+  cmovb :: a -> b -> CodeGen e s ()++instance Cmovb Reg32 Reg32 where+  cmovb (Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_reg x86_cc_b False dest source++instance Cmovb Reg32 Addr where+  cmovb (Reg32 dest) (Addr source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_mem x86_cc_b False dest source++instance Cmovb Reg32 (Disp, Reg32) where+  cmovb (Reg32 dest) (Disp disp, Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_b False dest source disp++instance Cmovb Reg32 Ind where+  cmovb (Reg32 dest) (Ind (Reg32 source)) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_b False dest source 0++class Cmovbe a b where+  cmovbe :: a -> b -> CodeGen e s ()++instance Cmovbe Reg32 Reg32 where+  cmovbe (Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_reg x86_cc_be False dest source++instance Cmovbe Reg32 Addr where+  cmovbe (Reg32 dest) (Addr source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_mem x86_cc_be False dest source++instance Cmovbe Reg32 (Disp, Reg32) where+  cmovbe (Reg32 dest) (Disp disp, Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_be False dest source disp++instance Cmovbe Reg32 Ind where+  cmovbe (Reg32 dest) (Ind (Reg32 source)) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_be False dest source 0++class Cmovc a b where+  cmovc :: a -> b -> CodeGen e s ()++instance Cmovc Reg32 Reg32 where+  cmovc (Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_reg x86_cc_c False dest source++instance Cmovc Reg32 Addr where+  cmovc (Reg32 dest) (Addr source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_mem x86_cc_c False dest source++instance Cmovc Reg32 (Disp, Reg32) where+  cmovc (Reg32 dest) (Disp disp, Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_c False dest source disp++instance Cmovc Reg32 Ind where+  cmovc (Reg32 dest) (Ind (Reg32 source)) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_c False dest source 0++class Cmove a b where+  cmove :: a -> b -> CodeGen e s ()++instance Cmove Reg32 Reg32 where+  cmove (Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_reg x86_cc_e False dest source++instance Cmove Reg32 Addr where+  cmove (Reg32 dest) (Addr source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_mem x86_cc_e False dest source++instance Cmove Reg32 (Disp, Reg32) where+  cmove (Reg32 dest) (Disp disp, Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_e False dest source disp++instance Cmove Reg32 Ind where+  cmove (Reg32 dest) (Ind (Reg32 source)) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_e False dest source 0++class Cmovna a b where+  cmovna :: a -> b -> CodeGen e s ()++instance Cmovna Reg32 Reg32 where+  cmovna (Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_reg x86_cc_na False dest source++instance Cmovna Reg32 Addr where+  cmovna (Reg32 dest) (Addr source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_mem x86_cc_na False dest source++instance Cmovna Reg32 (Disp, Reg32) where+  cmovna (Reg32 dest) (Disp disp, Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_na False dest source disp++instance Cmovna Reg32 Ind where+  cmovna (Reg32 dest) (Ind (Reg32 source)) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_na False dest source 0++class Cmovnae a b where+  cmovnae :: a -> b -> CodeGen e s ()++instance Cmovnae Reg32 Reg32 where+  cmovnae (Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_reg x86_cc_nae False dest source++instance Cmovnae Reg32 Addr where+  cmovnae (Reg32 dest) (Addr source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_mem x86_cc_nae False dest source++instance Cmovnae Reg32 (Disp, Reg32) where+  cmovnae (Reg32 dest) (Disp disp, Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_nae False dest source disp++instance Cmovnae Reg32 Ind where+  cmovnae (Reg32 dest) (Ind (Reg32 source)) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_nae False dest source 0++class Cmovnb a b where+  cmovnb :: a -> b -> CodeGen e s ()++instance Cmovnb Reg32 Reg32 where+  cmovnb (Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_reg x86_cc_nb False dest source++instance Cmovnb Reg32 Addr where+  cmovnb (Reg32 dest) (Addr source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_mem x86_cc_nb False dest source++instance Cmovnb Reg32 (Disp, Reg32) where+  cmovnb (Reg32 dest) (Disp disp, Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_nb False dest source disp++instance Cmovnb Reg32 Ind where+  cmovnb (Reg32 dest) (Ind (Reg32 source)) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_nb False dest source 0++class Cmovnbe a b where+  cmovnbe :: a -> b -> CodeGen e s ()++instance Cmovnbe Reg32 Reg32 where+  cmovnbe (Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_reg x86_cc_nbe False dest source++instance Cmovnbe Reg32 Addr where+  cmovnbe (Reg32 dest) (Addr source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_mem x86_cc_nbe False dest source++instance Cmovnbe Reg32 (Disp, Reg32) where+  cmovnbe (Reg32 dest) (Disp disp, Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_nbe False dest source disp++instance Cmovnbe Reg32 Ind where+  cmovnbe (Reg32 dest) (Ind (Reg32 source)) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_nbe False dest source 0++class Cmovnc a b where+  cmovnc :: a -> b -> CodeGen e s ()++instance Cmovnc Reg32 Reg32 where+  cmovnc (Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_reg x86_cc_nc False dest source++instance Cmovnc Reg32 Addr where+  cmovnc (Reg32 dest) (Addr source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_mem x86_cc_nc False dest source++instance Cmovnc Reg32 (Disp, Reg32) where+  cmovnc (Reg32 dest) (Disp disp, Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_nc False dest source disp++instance Cmovnc Reg32 Ind where+  cmovnc (Reg32 dest) (Ind (Reg32 source)) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_nc False dest source 0++class Cmovne a b where+  cmovne :: a -> b -> CodeGen e s ()++instance Cmovne Reg32 Reg32 where+  cmovne (Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_reg x86_cc_ne False dest source++instance Cmovne Reg32 Addr where+  cmovne (Reg32 dest) (Addr source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_mem x86_cc_ne False dest source++instance Cmovne Reg32 (Disp, Reg32) where+  cmovne (Reg32 dest) (Disp disp, Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_ne False dest source disp++instance Cmovne Reg32 Ind where+  cmovne (Reg32 dest) (Ind (Reg32 source)) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_ne False dest source 0++class Cmovnp a b where+  cmovnp :: a -> b -> CodeGen e s ()++instance Cmovnp Reg32 Reg32 where+  cmovnp (Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_reg x86_cc_np False dest source++instance Cmovnp Reg32 Addr where+  cmovnp (Reg32 dest) (Addr source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_mem x86_cc_np False dest source++instance Cmovnp Reg32 (Disp, Reg32) where+  cmovnp (Reg32 dest) (Disp disp, Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_np False dest source disp++instance Cmovnp Reg32 Ind where+  cmovnp (Reg32 dest) (Ind (Reg32 source)) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_np False dest source 0++class Cmovnz a b where+  cmovnz :: a -> b -> CodeGen e s ()++instance Cmovnz Reg32 Reg32 where+  cmovnz (Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_reg x86_cc_nz False dest source++instance Cmovnz Reg32 Addr where+  cmovnz (Reg32 dest) (Addr source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_mem x86_cc_nz False dest source++instance Cmovnz Reg32 (Disp, Reg32) where+  cmovnz (Reg32 dest) (Disp disp, Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_nz False dest source disp++instance Cmovnz Reg32 Ind where+  cmovnz (Reg32 dest) (Ind (Reg32 source)) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_nz False dest source 0++class Cmovp a b where+  cmovp :: a -> b -> CodeGen e s ()++instance Cmovp Reg32 Reg32 where+  cmovp (Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_reg x86_cc_p False dest source++instance Cmovp Reg32 Addr where+  cmovp (Reg32 dest) (Addr source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_mem x86_cc_p False dest source++instance Cmovp Reg32 (Disp, Reg32) where+  cmovp (Reg32 dest) (Disp disp, Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_p False dest source disp++instance Cmovp Reg32 Ind where+  cmovp (Reg32 dest) (Ind (Reg32 source)) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_p False dest source 0++class Cmovpe a b where+  cmovpe :: a -> b -> CodeGen e s ()++instance Cmovpe Reg32 Reg32 where+  cmovpe (Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_reg x86_cc_pe False dest source++instance Cmovpe Reg32 Addr where+  cmovpe (Reg32 dest) (Addr source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_mem x86_cc_pe False dest source++instance Cmovpe Reg32 (Disp, Reg32) where+  cmovpe (Reg32 dest) (Disp disp, Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_pe False dest source disp++instance Cmovpe Reg32 Ind where+  cmovpe (Reg32 dest) (Ind (Reg32 source)) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_pe False dest source 0++class Cmovpo a b where+  cmovpo :: a -> b -> CodeGen e s ()++instance Cmovpo Reg32 Reg32 where+  cmovpo (Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_reg x86_cc_po False dest source++instance Cmovpo Reg32 Addr where+  cmovpo (Reg32 dest) (Addr source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_mem x86_cc_po False dest source++instance Cmovpo Reg32 (Disp, Reg32) where+  cmovpo (Reg32 dest) (Disp disp, Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_po False dest source disp++instance Cmovpo Reg32 Ind where+  cmovpo (Reg32 dest) (Ind (Reg32 source)) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_po False dest source 0++class Cmovz a b where+  cmovz :: a -> b -> CodeGen e s ()++instance Cmovz Reg32 Reg32 where+  cmovz (Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_reg x86_cc_z False dest source++instance Cmovz Reg32 Addr where+  cmovz (Reg32 dest) (Addr source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_mem x86_cc_z False dest source++instance Cmovz Reg32 (Disp, Reg32) where+  cmovz (Reg32 dest) (Disp disp, Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_z False dest source disp++instance Cmovz Reg32 Ind where+  cmovz (Reg32 dest) (Ind (Reg32 source)) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_z False dest source 0++class Cmovg a b where+  cmovg :: a -> b -> CodeGen e s ()++instance Cmovg Reg32 Reg32 where+  cmovg (Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_reg x86_cc_gt True dest source++instance Cmovg Reg32 Addr where+  cmovg (Reg32 dest) (Addr source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_mem x86_cc_gt True dest source++instance Cmovg Reg32 (Disp, Reg32) where+  cmovg (Reg32 dest) (Disp disp, Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_gt True dest source disp++instance Cmovg Reg32 Ind where+  cmovg (Reg32 dest) (Ind (Reg32 source)) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_gt True dest source 0++class Cmovge a b where+  cmovge :: a -> b -> CodeGen e s ()++instance Cmovge Reg32 Reg32 where+  cmovge (Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_reg x86_cc_ge True dest source++instance Cmovge Reg32 Addr where+  cmovge (Reg32 dest) (Addr source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_mem x86_cc_ge True dest source++instance Cmovge Reg32 (Disp, Reg32) where+  cmovge (Reg32 dest) (Disp disp, Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_ge True dest source disp++instance Cmovge Reg32 Ind where+  cmovge (Reg32 dest) (Ind (Reg32 source)) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_ge True dest source 0++class Cmovl a b where+  cmovl :: a -> b -> CodeGen e s ()++instance Cmovl Reg32 Reg32 where+  cmovl (Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_reg x86_cc_lt True dest source++instance Cmovl Reg32 Addr where+  cmovl (Reg32 dest) (Addr source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_mem x86_cc_lt True dest source++instance Cmovl Reg32 (Disp, Reg32) where+  cmovl (Reg32 dest) (Disp disp, Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_lt True dest source disp++instance Cmovl Reg32 Ind where+  cmovl (Reg32 dest) (Ind (Reg32 source)) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_lt True dest source 0++class Cmovle a b where+  cmovle :: a -> b -> CodeGen e s ()++instance Cmovle Reg32 Reg32 where+  cmovle (Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_reg x86_cc_le True dest source++instance Cmovle Reg32 Addr where+  cmovle (Reg32 dest) (Addr source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_mem x86_cc_le True dest source++instance Cmovle Reg32 (Disp, Reg32) where+  cmovle (Reg32 dest) (Disp disp, Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_le True dest source disp++instance Cmovle Reg32 Ind where+  cmovle (Reg32 dest) (Ind (Reg32 source)) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_le True dest source 0++class Cmovng a b where+  cmovng :: a -> b -> CodeGen e s ()++instance Cmovng Reg32 Reg32 where+  cmovng (Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_reg x86_cc_le True dest source++instance Cmovng Reg32 Addr where+  cmovng (Reg32 dest) (Addr source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_mem x86_cc_le True dest source++instance Cmovng Reg32 (Disp, Reg32) where+  cmovng (Reg32 dest) (Disp disp, Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_le True dest source disp++instance Cmovng Reg32 Ind where+  cmovng (Reg32 dest) (Ind (Reg32 source)) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_le True dest source 0++class Cmovnge a b where+  cmovnge :: a -> b -> CodeGen e s ()++instance Cmovnge Reg32 Reg32 where+  cmovnge (Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_reg x86_cc_lt True dest source++instance Cmovnge Reg32 Addr where+  cmovnge (Reg32 dest) (Addr source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_mem x86_cc_lt True dest source++instance Cmovnge Reg32 (Disp, Reg32) where+  cmovnge (Reg32 dest) (Disp disp, Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_lt True dest source disp++instance Cmovnge Reg32 Ind where+  cmovnge (Reg32 dest) (Ind (Reg32 source)) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_lt True dest source 0++class Cmovnl a b where+  cmovnl :: a -> b -> CodeGen e s ()++instance Cmovnl Reg32 Reg32 where+  cmovnl (Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_reg x86_cc_ge True dest source++instance Cmovnl Reg32 Addr where+  cmovnl (Reg32 dest) (Addr source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_mem x86_cc_ge True dest source++instance Cmovnl Reg32 (Disp, Reg32) where+  cmovnl (Reg32 dest) (Disp disp, Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_ge True dest source disp++instance Cmovnl Reg32 Ind where+  cmovnl (Reg32 dest) (Ind (Reg32 source)) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_ge True dest source 0++class Cmovnle a b where+  cmovnle :: a -> b -> CodeGen e s ()++instance Cmovnle Reg32 Reg32 where+  cmovnle (Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_reg x86_cc_gt True dest source++instance Cmovnle Reg32 Addr where+  cmovnle (Reg32 dest) (Addr source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_mem x86_cc_gt True dest source++instance Cmovnle Reg32 (Disp, Reg32) where+  cmovnle (Reg32 dest) (Disp disp, Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_gt True dest source disp++instance Cmovnle Reg32 Ind where+  cmovnle (Reg32 dest) (Ind (Reg32 source)) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_gt True dest source 0++class Cmovno a b where+  cmovno :: a -> b -> CodeGen e s ()++instance Cmovno Reg32 Reg32 where+  cmovno (Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_reg x86_cc_no True dest source++instance Cmovno Reg32 Addr where+  cmovno (Reg32 dest) (Addr source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_mem x86_cc_no True dest source++instance Cmovno Reg32 (Disp, Reg32) where+  cmovno (Reg32 dest) (Disp disp, Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_no True dest source disp++instance Cmovno Reg32 Ind where+  cmovno (Reg32 dest) (Ind (Reg32 source)) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_no True dest source 0++class Cmovns a b where+  cmovns :: a -> b -> CodeGen e s ()++instance Cmovns Reg32 Reg32 where+  cmovns (Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_reg x86_cc_ns True dest source++instance Cmovns Reg32 Addr where+  cmovns (Reg32 dest) (Addr source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_mem x86_cc_ns True dest source++instance Cmovns Reg32 (Disp, Reg32) where+  cmovns (Reg32 dest) (Disp disp, Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_ns True dest source disp++instance Cmovns Reg32 Ind where+  cmovns (Reg32 dest) (Ind (Reg32 source)) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_ns True dest source 0++class Cmovo a b where+  cmovo :: a -> b -> CodeGen e s ()++instance Cmovo Reg32 Reg32 where+  cmovo (Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_reg x86_cc_o True dest source++instance Cmovo Reg32 Addr where+  cmovo (Reg32 dest) (Addr source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_mem x86_cc_o True dest source++instance Cmovo Reg32 (Disp, Reg32) where+  cmovo (Reg32 dest) (Disp disp, Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_o True dest source disp++instance Cmovo Reg32 Ind where+  cmovo (Reg32 dest) (Ind (Reg32 source)) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_o True dest source 0++class Cmovs a b where+  cmovs :: a -> b -> CodeGen e s ()++instance Cmovs Reg32 Reg32 where+  cmovs (Reg32 dest) (Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_reg x86_cc_s True dest source++instance Cmovs Reg32 Addr where+  cmovs (Reg32 dest) (Addr source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_mem x86_cc_s True dest source++instance Cmovs Reg32 (Disp, Reg32) where+  cmovs (Reg32 dest) (Disp disp, Reg32 source) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_s True dest source disp++instance Cmovs Reg32 Ind where+  cmovs (Reg32 dest) (Ind (Reg32 source)) = ensureBufferSize x86_max_instruction_bytes >> x86_cmov_membase x86_cc_s True dest source 0+++-- release stack frame++leave :: CodeGen e s ()+leave = ensureBufferSize x86_max_instruction_bytes >> x86_leave+++-- store ah into flags++sahf :: CodeGen e s ()+sahf = ensureBufferSize x86_max_instruction_bytes >> x86_sahf++-- Floating point instructions++fldz = ensureBufferSize x86_max_instruction_bytes >> x86_fldz+fld1 = ensureBufferSize x86_max_instruction_bytes >> x86_fld1+fldpi = ensureBufferSize x86_max_instruction_bytes >> x86_fldpi++fstsw = ensureBufferSize x86_max_instruction_bytes >> x86_fstsw+fnstsw = ensureBufferSize x86_max_instruction_bytes >> x86_fstsw++fcompp = ensureBufferSize x86_max_instruction_bytes >> x86_fcompp+fucompp = ensureBufferSize x86_max_instruction_bytes >> x86_fucompp++fchs = ensureBufferSize x86_max_instruction_bytes >> x86_fchs+frem = ensureBufferSize x86_max_instruction_bytes >> x86_frem++fxch (FPReg idx) = ensureBufferSize x86_max_instruction_bytes >> x86_fxch idx++fcomi (FPReg idx) = ensureBufferSize x86_max_instruction_bytes >> x86_fcomi idx+fcomip (FPReg idx) = ensureBufferSize x86_max_instruction_bytes >> x86_fcomip idx+fucomi (FPReg idx) = ensureBufferSize x86_max_instruction_bytes >> x86_fucomi idx+fucomip (FPReg idx) = ensureBufferSize x86_max_instruction_bytes >> x86_fucomip idx++class Fadd a b where+    fadd :: a -> b -> CodeGen e s ()++instance Fadd FPTopReg FPReg where+    fadd FPTopReg (FPReg idx) = ensureBufferSize x86_max_instruction_bytes >> x86_fp_op x86_fadd idx++instance Fadd FPTopReg Addr where+    fadd FPTopReg (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_fp_op_mem x86_fadd a True++instance Fadd FPTopReg (Disp, Reg32) where+    fadd FPTopReg (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_fp_op_membase x86_fadd r d True++instance Fadd FPTopReg Ind where+    fadd FPTopReg (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_fp_op_membase x86_fadd r 0 True+++class Fsub a b where+    fsub :: a -> b -> CodeGen e s ()++instance Fsub FPTopReg FPReg where+    fsub FPTopReg (FPReg idx) = ensureBufferSize x86_max_instruction_bytes >> x86_fp_op x86_fsub idx++instance Fsub FPTopReg Addr where+    fsub FPTopReg (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_fp_op_mem x86_fsub a True++instance Fsub FPTopReg (Disp, Reg32) where+    fsub FPTopReg (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_fp_op_membase x86_fsub r d True++instance Fsub FPTopReg Ind where+    fsub FPTopReg (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_fp_op_membase x86_fsub r 0 True+++class Fsubr a b where+    fsubr :: a -> b -> CodeGen e s ()++instance Fsubr FPTopReg FPReg where+    fsubr FPTopReg (FPReg idx) = ensureBufferSize x86_max_instruction_bytes >> x86_fp_op x86_fsubr idx++instance Fsubr FPTopReg Addr where+    fsubr FPTopReg (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_fp_op_mem x86_fsubr a True++instance Fsubr FPTopReg (Disp, Reg32) where+    fsubr FPTopReg (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_fp_op_membase x86_fsubr r d True++instance Fsubr FPTopReg Ind where+    fsubr FPTopReg (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_fp_op_membase x86_fsubr r 0 True+++class Fmul a b where+    fmul :: a -> b -> CodeGen e s ()++instance Fmul FPTopReg FPReg where+    fmul FPTopReg (FPReg idx) = ensureBufferSize x86_max_instruction_bytes >> x86_fp_op x86_fmul idx++instance Fmul FPTopReg Addr where+    fmul FPTopReg (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_fp_op_mem x86_fmul a True++instance Fmul FPTopReg (Disp, Reg32) where+    fmul FPTopReg (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_fp_op_membase x86_fmul r d True++instance Fmul FPTopReg Ind where+    fmul FPTopReg (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_fp_op_membase x86_fmul r 0 True+++class Fdiv a b where+    fdiv :: a -> b -> CodeGen e s ()++instance Fdiv FPTopReg FPReg where+    fdiv FPTopReg (FPReg idx) = ensureBufferSize x86_max_instruction_bytes >> x86_fp_op x86_fdiv idx++instance Fdiv FPTopReg Addr where+    fdiv FPTopReg (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_fp_op_mem x86_fdiv a True++instance Fdiv FPTopReg (Disp, Reg32) where+    fdiv FPTopReg (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_fp_op_membase x86_fdiv r d True++instance Fdiv FPTopReg Ind where+    fdiv FPTopReg (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_fp_op_membase x86_fdiv r 0 True+++class Fdivr a b where+    fdivr :: a -> b -> CodeGen e s ()++instance Fdivr FPTopReg FPReg where+    fdivr FPTopReg (FPReg idx) = ensureBufferSize x86_max_instruction_bytes >> x86_fp_op x86_fdivr idx++instance Fdivr FPTopReg Addr where+    fdivr FPTopReg (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_fp_op_mem x86_fdivr a True++instance Fdivr FPTopReg (Disp, Reg32) where+    fdivr FPTopReg (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_fp_op_membase x86_fdivr r d True++instance Fdivr FPTopReg Ind where+    fdivr FPTopReg (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_fp_op_membase x86_fdivr r 0 True+++class Fcom a b where+    fcom :: a -> b -> CodeGen e s ()++instance Fcom FPTopReg FPReg where+    fcom FPTopReg (FPReg idx) = ensureBufferSize x86_max_instruction_bytes >> x86_fp_op x86_fcom idx++instance Fcom FPTopReg Addr where+    fcom FPTopReg (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_fp_op_mem x86_fcom a True++instance Fcom FPTopReg (Disp, Reg32) where+    fcom FPTopReg (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_fp_op_membase x86_fcom r d True++instance Fcom FPTopReg Ind where+    fcom FPTopReg (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_fp_op_membase x86_fcom r 0 True+++class Fcomp a b where+    fcomp :: a -> b -> CodeGen e s ()++instance Fcomp FPTopReg FPReg where+    fcomp FPTopReg (FPReg idx) = ensureBufferSize x86_max_instruction_bytes >> x86_fp_op x86_fcomp idx++instance Fcomp FPTopReg Addr where+    fcomp FPTopReg (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_fp_op_mem x86_fcomp a True++instance Fcomp FPTopReg (Disp, Reg32) where+    fcomp FPTopReg (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_fp_op_membase x86_fcomp r d True++instance Fcomp FPTopReg Ind where+    fcomp FPTopReg (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_fp_op_membase x86_fcomp r 0 True+++class Fld a b where+    fld :: a -> b -> CodeGen e s ()++instance Fld FPTopReg FPReg where+    fld FPTopReg (FPReg idx) = ensureBufferSize x86_max_instruction_bytes >> x86_fld_reg idx++instance Fld FPTopReg Addr where +    fld FPTopReg (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_fld a True++instance Fld FPTopReg (Disp, Reg32) where +    fld FPTopReg (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_fld_membase r d True++instance Fld FPTopReg Ind where +    fld FPTopReg (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_fld_membase r 0 True++class Fld80 a b where+    fld80 :: a -> b -> CodeGen e s ()++instance Fld80 FPTopReg Addr where +    fld80 FPTopReg (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_fld80_mem a++instance Fld80 FPTopReg (Disp, Reg32) where +    fld80 FPTopReg (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_fld80_membase r d++instance Fld80 FPTopReg Ind where +    fld80 FPTopReg (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_fld80_membase r 0++class Fst a where+    fst :: a -> CodeGen e s ()++instance Fst Addr where+    fst (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_fst a True False++instance Fst (Disp, Reg32) where+    fst (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_fst_membase r d True False++instance Fst Ind where+    fst (Ind (Reg32 r)) =  ensureBufferSize x86_max_instruction_bytes >> x86_fst_membase r 0 True False++class Fstp a where+    fstp :: a -> CodeGen e s ()++instance Fstp FPReg where+    fstp (FPReg r) = ensureBufferSize x86_max_instruction_bytes >> x86_fstp r++instance Fstp Addr where+    fstp (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_fst a True True++instance Fstp (Disp, Reg32) where+    fstp (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_fst_membase r d True True++instance Fstp Ind where+    fstp (Ind (Reg32 r)) =  ensureBufferSize x86_max_instruction_bytes >> x86_fst_membase r 0 True True+++class Fst80 a where+    fst80 :: a -> CodeGen e s ()++instance Fst80 Addr where+    fst80 (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_fst80_mem a++instance Fst80 (Disp, Reg32) where+    fst80 (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_fst80_membase r d++instance Fst80 Ind where+    fst80 (Ind (Reg32 r)) =  ensureBufferSize x86_max_instruction_bytes >> x86_fst80_membase r 0+++class Fnstcw a where+    fnstcw :: a -> CodeGen e s ()++instance Fnstcw Addr where+    fnstcw (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_fnstcw a++instance Fnstcw (Disp, Reg32) where+    fnstcw (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_fnstcw_membase r d++instance Fnstcw Ind where+    fnstcw (Ind (Reg32 r)) =  ensureBufferSize x86_max_instruction_bytes >> x86_fnstcw_membase r 0+++class Fldcw a where+    fldcw :: a -> CodeGen e s ()++instance Fldcw Addr where+    fldcw (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_fldcw a++instance Fldcw (Disp, Reg32) where+    fldcw (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_fldcw_membase r d++instance Fldcw Ind where+    fldcw (Ind (Reg32 r)) =  ensureBufferSize x86_max_instruction_bytes >> x86_fldcw_membase r 0+++class Fild a where+    fild :: a -> CodeGen e s ()++instance Fild Addr where +    fild (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_fild a False++instance Fild (Disp, Reg32) where +    fild (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_fild_membase r d False++instance Fild Ind where +    fild (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_fild_membase r 0 False+++class Fist a where+    fist :: a -> CodeGen e s ()++instance Fist (Disp, Reg32) where +    fist (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_fist_membase r d False++instance Fist Ind where +    fist (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_fist_membase r 0 False+++class Fistp a where+    fistp :: a -> CodeGen e s ()++instance Fistp Addr where+    fistp (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_fist_pop a False++instance Fistp (Disp, Reg32) where +    fistp (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_fist_pop_membase r d False++instance Fistp Ind where +    fistp (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_fist_pop_membase r 0 False+++class Sqrtsd a b where+    sqrtsd :: a -> b -> CodeGen e s ()++instance Sqrtsd XMMReg XMMReg where+    sqrtsd (XMMReg xd) (XMMReg xs) = ensureBufferSize x86_max_instruction_bytes >> x86_sqrt_sse_reg_reg x86_sse_sd xd xs++instance Sqrtsd XMMReg Addr where+    sqrtsd (XMMReg xd) (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_sqrt_sse_reg_mem x86_sse_sd xd a++instance Sqrtsd XMMReg Ind where+    sqrtsd (XMMReg xd) (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_sqrt_sse_reg_membase x86_sse_sd xd r 0++instance Sqrtsd XMMReg (Disp, Reg32) where+    sqrtsd (XMMReg xd) (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_sqrt_sse_reg_membase x86_sse_sd xd r d+++class Sqrtss a b where+    sqrtss :: a -> b -> CodeGen e s ()++instance Sqrtss XMMReg XMMReg where+    sqrtss (XMMReg xd) (XMMReg xs) = ensureBufferSize x86_max_instruction_bytes >> x86_sqrt_sse_reg_reg x86_sse_ss xd xs++instance Sqrtss XMMReg Addr where+    sqrtss (XMMReg xd) (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_sqrt_sse_reg_mem x86_sse_ss xd a++instance Sqrtss XMMReg Ind where+    sqrtss (XMMReg xd) (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_sqrt_sse_reg_membase x86_sse_ss xd r 0++instance Sqrtss XMMReg (Disp, Reg32) where+    sqrtss (XMMReg xd) (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_sqrt_sse_reg_membase x86_sse_ss xd r d+++class Sqrtpd a b where+    sqrtpd :: a -> b -> CodeGen e s ()++instance Sqrtpd XMMReg XMMReg where+    sqrtpd (XMMReg xd) (XMMReg xs) = ensureBufferSize x86_max_instruction_bytes >> x86_sqrt_sse_reg_reg x86_sse_pd xd xs++instance Sqrtpd XMMReg Addr where+    sqrtpd (XMMReg xd) (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_sqrt_sse_reg_mem x86_sse_pd xd a++instance Sqrtpd XMMReg Ind where+    sqrtpd (XMMReg xd) (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_sqrt_sse_reg_membase x86_sse_pd xd r 0++instance Sqrtpd XMMReg (Disp, Reg32) where+    sqrtpd (XMMReg xd) (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_sqrt_sse_reg_membase x86_sse_pd xd r d+++class Sqrtps a b where+    sqrtps :: a -> b -> CodeGen e s ()++instance Sqrtps XMMReg XMMReg where+    sqrtps (XMMReg xd) (XMMReg xs) = ensureBufferSize x86_max_instruction_bytes >> x86_sqrt_sse_reg_reg x86_sse_ps xd xs++instance Sqrtps XMMReg Addr where+    sqrtps (XMMReg xd) (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_sqrt_sse_reg_mem x86_sse_ps xd a++instance Sqrtps XMMReg Ind where+    sqrtps (XMMReg xd) (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_sqrt_sse_reg_membase x86_sse_ps xd r 0++instance Sqrtps XMMReg (Disp, Reg32) where+    sqrtps (XMMReg xd) (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_sqrt_sse_reg_membase x86_sse_ps xd r d+++class Addsd a b where+    addsd :: a -> b -> CodeGen e s ()++instance Addsd XMMReg XMMReg where+    addsd (XMMReg xd) (XMMReg xs) = ensureBufferSize x86_max_instruction_bytes >> x86_add_sse_reg_reg x86_sse_sd xd xs++instance Addsd XMMReg Addr where+    addsd (XMMReg xd) (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_add_sse_reg_mem x86_sse_sd xd a++instance Addsd XMMReg Ind where+    addsd (XMMReg xd) (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_add_sse_reg_membase x86_sse_sd xd r 0++instance Addsd XMMReg (Disp, Reg32) where+    addsd (XMMReg xd) (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_add_sse_reg_membase x86_sse_sd xd r d+++class Addss a b where+    addss :: a -> b -> CodeGen e s ()++instance Addss XMMReg XMMReg where+    addss (XMMReg xd) (XMMReg xs) = ensureBufferSize x86_max_instruction_bytes >> x86_add_sse_reg_reg x86_sse_ss xd xs++instance Addss XMMReg Addr where+    addss (XMMReg xd) (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_add_sse_reg_mem x86_sse_ss xd a++instance Addss XMMReg Ind where+    addss (XMMReg xd) (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_add_sse_reg_membase x86_sse_ss xd r 0++instance Addss XMMReg (Disp, Reg32) where+    addss (XMMReg xd) (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_add_sse_reg_membase x86_sse_ss xd r d+++class Addpd a b where+    addpd :: a -> b -> CodeGen e s ()++instance Addpd XMMReg XMMReg where+    addpd (XMMReg xd) (XMMReg xs) = ensureBufferSize x86_max_instruction_bytes >> x86_add_sse_reg_reg x86_sse_pd xd xs++instance Addpd XMMReg Addr where+    addpd (XMMReg xd) (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_add_sse_reg_mem x86_sse_pd xd a++instance Addpd XMMReg Ind where+    addpd (XMMReg xd) (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_add_sse_reg_membase x86_sse_pd xd r 0++instance Addpd XMMReg (Disp, Reg32) where+    addpd (XMMReg xd) (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_add_sse_reg_membase x86_sse_pd xd r d+++class Addps a b where+    addps :: a -> b -> CodeGen e s ()++instance Addps XMMReg XMMReg where+    addps (XMMReg xd) (XMMReg xs) = ensureBufferSize x86_max_instruction_bytes >> x86_add_sse_reg_reg x86_sse_ps xd xs++instance Addps XMMReg Addr where+    addps (XMMReg xd) (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_add_sse_reg_mem x86_sse_ps xd a++instance Addps XMMReg Ind where+    addps (XMMReg xd) (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_add_sse_reg_membase x86_sse_ps xd r 0++instance Addps XMMReg (Disp, Reg32) where+    addps (XMMReg xd) (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_add_sse_reg_membase x86_sse_ps xd r d++class Subsd a b where+    subsd :: a -> b -> CodeGen e s ()++instance Subsd XMMReg XMMReg where+    subsd (XMMReg xd) (XMMReg xs) = ensureBufferSize x86_max_instruction_bytes >> x86_sub_sse_reg_reg x86_sse_sd xd xs++instance Subsd XMMReg Addr where+    subsd (XMMReg xd) (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_sub_sse_reg_mem x86_sse_sd xd a++instance Subsd XMMReg Ind where+    subsd (XMMReg xd) (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_sub_sse_reg_membase x86_sse_sd xd r 0++instance Subsd XMMReg (Disp, Reg32) where+    subsd (XMMReg xd) (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_sub_sse_reg_membase x86_sse_sd xd r d+++class Subss a b where+    subss :: a -> b -> CodeGen e s ()++instance Subss XMMReg XMMReg where+    subss (XMMReg xd) (XMMReg xs) = ensureBufferSize x86_max_instruction_bytes >> x86_sub_sse_reg_reg x86_sse_ss xd xs++instance Subss XMMReg Addr where+    subss (XMMReg xd) (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_sub_sse_reg_mem x86_sse_ss xd a++instance Subss XMMReg Ind where+    subss (XMMReg xd) (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_sub_sse_reg_membase x86_sse_ss xd r 0++instance Subss XMMReg (Disp, Reg32) where+    subss (XMMReg xd) (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_sub_sse_reg_membase x86_sse_ss xd r d+++class Subpd a b where+    subpd :: a -> b -> CodeGen e s ()++instance Subpd XMMReg XMMReg where+    subpd (XMMReg xd) (XMMReg xs) = ensureBufferSize x86_max_instruction_bytes >> x86_sub_sse_reg_reg x86_sse_pd xd xs++instance Subpd XMMReg Addr where+    subpd (XMMReg xd) (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_sub_sse_reg_mem x86_sse_pd xd a++instance Subpd XMMReg Ind where+    subpd (XMMReg xd) (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_sub_sse_reg_membase x86_sse_pd xd r 0++instance Subpd XMMReg (Disp, Reg32) where+    subpd (XMMReg xd) (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_sub_sse_reg_membase x86_sse_pd xd r d+++class Subps a b where+    subps :: a -> b -> CodeGen e s ()++instance Subps XMMReg XMMReg where+    subps (XMMReg xd) (XMMReg xs) = ensureBufferSize x86_max_instruction_bytes >> x86_sub_sse_reg_reg x86_sse_ps xd xs++instance Subps XMMReg Addr where+    subps (XMMReg xd) (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_sub_sse_reg_mem x86_sse_ps xd a++instance Subps XMMReg Ind where+    subps (XMMReg xd) (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_sub_sse_reg_membase x86_sse_ps xd r 0++instance Subps XMMReg (Disp, Reg32) where+    subps (XMMReg xd) (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_sub_sse_reg_membase x86_sse_ps xd r d++class Mulsd a b where+    mulsd :: a -> b -> CodeGen e s ()++instance Mulsd XMMReg XMMReg where+    mulsd (XMMReg xd) (XMMReg xs) = ensureBufferSize x86_max_instruction_bytes >> x86_mul_sse_reg_reg x86_sse_sd xd xs++instance Mulsd XMMReg Addr where+    mulsd (XMMReg xd) (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_mul_sse_reg_mem x86_sse_sd xd a++instance Mulsd XMMReg Ind where+    mulsd (XMMReg xd) (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_mul_sse_reg_membase x86_sse_sd xd r 0++instance Mulsd XMMReg (Disp, Reg32) where+    mulsd (XMMReg xd) (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_mul_sse_reg_membase x86_sse_sd xd r d+++class Mulss a b where+    mulss :: a -> b -> CodeGen e s ()++instance Mulss XMMReg XMMReg where+    mulss (XMMReg xd) (XMMReg xs) = ensureBufferSize x86_max_instruction_bytes >> x86_mul_sse_reg_reg x86_sse_ss xd xs++instance Mulss XMMReg Addr where+    mulss (XMMReg xd) (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_mul_sse_reg_mem x86_sse_ss xd a++instance Mulss XMMReg Ind where+    mulss (XMMReg xd) (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_mul_sse_reg_membase x86_sse_ss xd r 0++instance Mulss XMMReg (Disp, Reg32) where+    mulss (XMMReg xd) (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_mul_sse_reg_membase x86_sse_ss xd r d+++class Mulpd a b where+    mulpd :: a -> b -> CodeGen e s ()++instance Mulpd XMMReg XMMReg where+    mulpd (XMMReg xd) (XMMReg xs) = ensureBufferSize x86_max_instruction_bytes >> x86_mul_sse_reg_reg x86_sse_pd xd xs++instance Mulpd XMMReg Addr where+    mulpd (XMMReg xd) (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_mul_sse_reg_mem x86_sse_pd xd a++instance Mulpd XMMReg Ind where+    mulpd (XMMReg xd) (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_mul_sse_reg_membase x86_sse_pd xd r 0++instance Mulpd XMMReg (Disp, Reg32) where+    mulpd (XMMReg xd) (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_mul_sse_reg_membase x86_sse_pd xd r d+++class Mulps a b where+    mulps :: a -> b -> CodeGen e s ()++instance Mulps XMMReg XMMReg where+    mulps (XMMReg xd) (XMMReg xs) = ensureBufferSize x86_max_instruction_bytes >> x86_mul_sse_reg_reg x86_sse_ps xd xs++instance Mulps XMMReg Addr where+    mulps (XMMReg xd) (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_mul_sse_reg_mem x86_sse_ps xd a++instance Mulps XMMReg Ind where+    mulps (XMMReg xd) (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_mul_sse_reg_membase x86_sse_ps xd r 0++instance Mulps XMMReg (Disp, Reg32) where+    mulps (XMMReg xd) (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_mul_sse_reg_membase x86_sse_ps xd r d+++class Divsd a b where+    divsd :: a -> b -> CodeGen e s ()++instance Divsd XMMReg XMMReg where+    divsd (XMMReg xd) (XMMReg xs) = ensureBufferSize x86_max_instruction_bytes >> x86_div_sse_reg_reg x86_sse_sd xd xs++instance Divsd XMMReg Addr where+    divsd (XMMReg xd) (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_div_sse_reg_mem x86_sse_sd xd a++instance Divsd XMMReg Ind where+    divsd (XMMReg xd) (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_div_sse_reg_membase x86_sse_sd xd r 0++instance Divsd XMMReg (Disp, Reg32) where+    divsd (XMMReg xd) (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_div_sse_reg_membase x86_sse_sd xd r d+++class Divss a b where+    divss :: a -> b -> CodeGen e s ()++instance Divss XMMReg XMMReg where+    divss (XMMReg xd) (XMMReg xs) = ensureBufferSize x86_max_instruction_bytes >> x86_div_sse_reg_reg x86_sse_ss xd xs++instance Divss XMMReg Addr where+    divss (XMMReg xd) (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_div_sse_reg_mem x86_sse_ss xd a++instance Divss XMMReg Ind where+    divss (XMMReg xd) (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_div_sse_reg_membase x86_sse_ss xd r 0++instance Divss XMMReg (Disp, Reg32) where+    divss (XMMReg xd) (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_div_sse_reg_membase x86_sse_ss xd r d+++class Divpd a b where+    divpd :: a -> b -> CodeGen e s ()++instance Divpd XMMReg XMMReg where+    divpd (XMMReg xd) (XMMReg xs) = ensureBufferSize x86_max_instruction_bytes >> x86_div_sse_reg_reg x86_sse_pd xd xs++instance Divpd XMMReg Addr where+    divpd (XMMReg xd) (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_div_sse_reg_mem x86_sse_pd xd a++instance Divpd XMMReg Ind where+    divpd (XMMReg xd) (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_div_sse_reg_membase x86_sse_pd xd r 0++instance Divpd XMMReg (Disp, Reg32) where+    divpd (XMMReg xd) (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_div_sse_reg_membase x86_sse_pd xd r d+++class Divps a b where+    divps :: a -> b -> CodeGen e s ()++instance Divps XMMReg XMMReg where+    divps (XMMReg xd) (XMMReg xs) = ensureBufferSize x86_max_instruction_bytes >> x86_div_sse_reg_reg x86_sse_ps xd xs++instance Divps XMMReg Addr where+    divps (XMMReg xd) (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_div_sse_reg_mem x86_sse_ps xd a++instance Divps XMMReg Ind where+    divps (XMMReg xd) (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_div_sse_reg_membase x86_sse_ps xd r 0++instance Divps XMMReg (Disp, Reg32) where+    divps (XMMReg xd) (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_div_sse_reg_membase x86_sse_ps xd r d++class Minsd a b where+    minsd :: a -> b -> CodeGen e s ()++instance Minsd XMMReg XMMReg where+    minsd (XMMReg xd) (XMMReg xs) = ensureBufferSize x86_max_instruction_bytes >> x86_min_sse_reg_reg x86_sse_sd xd xs++instance Minsd XMMReg Addr where+    minsd (XMMReg xd) (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_min_sse_reg_mem x86_sse_sd xd a++instance Minsd XMMReg Ind where+    minsd (XMMReg xd) (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_min_sse_reg_membase x86_sse_sd xd r 0++instance Minsd XMMReg (Disp, Reg32) where+    minsd (XMMReg xd) (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_min_sse_reg_membase x86_sse_sd xd r d+++class Minss a b where+    minss :: a -> b -> CodeGen e s ()++instance Minss XMMReg XMMReg where+    minss (XMMReg xd) (XMMReg xs) = ensureBufferSize x86_max_instruction_bytes >> x86_min_sse_reg_reg x86_sse_ss xd xs++instance Minss XMMReg Addr where+    minss (XMMReg xd) (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_min_sse_reg_mem x86_sse_ss xd a++instance Minss XMMReg Ind where+    minss (XMMReg xd) (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_min_sse_reg_membase x86_sse_ss xd r 0++instance Minss XMMReg (Disp, Reg32) where+    minss (XMMReg xd) (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_min_sse_reg_membase x86_sse_ss xd r d+++class Minpd a b where+    minpd :: a -> b -> CodeGen e s ()++instance Minpd XMMReg XMMReg where+    minpd (XMMReg xd) (XMMReg xs) = ensureBufferSize x86_max_instruction_bytes >> x86_min_sse_reg_reg x86_sse_pd xd xs++instance Minpd XMMReg Addr where+    minpd (XMMReg xd) (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_min_sse_reg_mem x86_sse_pd xd a++instance Minpd XMMReg Ind where+    minpd (XMMReg xd) (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_min_sse_reg_membase x86_sse_pd xd r 0++instance Minpd XMMReg (Disp, Reg32) where+    minpd (XMMReg xd) (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_min_sse_reg_membase x86_sse_pd xd r d+++class Minps a b where+    minps :: a -> b -> CodeGen e s ()++instance Minps XMMReg XMMReg where+    minps (XMMReg xd) (XMMReg xs) = ensureBufferSize x86_max_instruction_bytes >> x86_min_sse_reg_reg x86_sse_ps xd xs++instance Minps XMMReg Addr where+    minps (XMMReg xd) (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_min_sse_reg_mem x86_sse_ps xd a++instance Minps XMMReg Ind where+    minps (XMMReg xd) (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_min_sse_reg_membase x86_sse_ps xd r 0++instance Minps XMMReg (Disp, Reg32) where+    minps (XMMReg xd) (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_min_sse_reg_membase x86_sse_ps xd r d+++class Maxsd a b where+    maxsd :: a -> b -> CodeGen e s ()++instance Maxsd XMMReg XMMReg where+    maxsd (XMMReg xd) (XMMReg xs) = ensureBufferSize x86_max_instruction_bytes >> x86_max_sse_reg_reg x86_sse_sd xd xs++instance Maxsd XMMReg Addr where+    maxsd (XMMReg xd) (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_max_sse_reg_mem x86_sse_sd xd a++instance Maxsd XMMReg Ind where+    maxsd (XMMReg xd) (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_max_sse_reg_membase x86_sse_sd xd r 0++instance Maxsd XMMReg (Disp, Reg32) where+    maxsd (XMMReg xd) (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_max_sse_reg_membase x86_sse_sd xd r d+++class Maxss a b where+    maxss :: a -> b -> CodeGen e s ()++instance Maxss XMMReg XMMReg where+    maxss (XMMReg xd) (XMMReg xs) = ensureBufferSize x86_max_instruction_bytes >> x86_max_sse_reg_reg x86_sse_ss xd xs++instance Maxss XMMReg Addr where+    maxss (XMMReg xd) (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_max_sse_reg_mem x86_sse_ss xd a++instance Maxss XMMReg Ind where+    maxss (XMMReg xd) (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_max_sse_reg_membase x86_sse_ss xd r 0++instance Maxss XMMReg (Disp, Reg32) where+    maxss (XMMReg xd) (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_max_sse_reg_membase x86_sse_ss xd r d+++class Maxpd a b where+    maxpd :: a -> b -> CodeGen e s ()++instance Maxpd XMMReg XMMReg where+    maxpd (XMMReg xd) (XMMReg xs) = ensureBufferSize x86_max_instruction_bytes >> x86_max_sse_reg_reg x86_sse_pd xd xs++instance Maxpd XMMReg Addr where+    maxpd (XMMReg xd) (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_max_sse_reg_mem x86_sse_pd xd a++instance Maxpd XMMReg Ind where+    maxpd (XMMReg xd) (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_max_sse_reg_membase x86_sse_pd xd r 0++instance Maxpd XMMReg (Disp, Reg32) where+    maxpd (XMMReg xd) (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_max_sse_reg_membase x86_sse_pd xd r d+++class Maxps a b where+    maxps :: a -> b -> CodeGen e s ()++instance Maxps XMMReg XMMReg where+    maxps (XMMReg xd) (XMMReg xs) = ensureBufferSize x86_max_instruction_bytes >> x86_max_sse_reg_reg x86_sse_ps xd xs++instance Maxps XMMReg Addr where+    maxps (XMMReg xd) (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_max_sse_reg_mem x86_sse_ps xd a++instance Maxps XMMReg Ind where+    maxps (XMMReg xd) (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_max_sse_reg_membase x86_sse_ps xd r 0++instance Maxps XMMReg (Disp, Reg32) where+    maxps (XMMReg xd) (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_max_sse_reg_membase x86_sse_ps xd r d+++class Movsd a b where+    movsd :: a -> b -> CodeGen e s ()++instance Movsd XMMReg XMMReg where+    movsd (XMMReg xd) (XMMReg xs) = ensureBufferSize x86_max_instruction_bytes >> x86_mov_sse_reg_reg x86_sse_sd xd xs++instance Movsd XMMReg Addr where+    movsd (XMMReg xd) (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_mov_sse_reg_mem x86_sse_sd xd a++instance Movsd Addr XMMReg where+    movsd (Addr a) (XMMReg xd) = ensureBufferSize x86_max_instruction_bytes >> x86_mov_sse_mem_reg x86_sse_sd a xd++instance Movsd XMMReg Ind where+    movsd (XMMReg xd) (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_mov_sse_reg_membase x86_sse_sd xd r 0++instance Movsd Ind XMMReg where+    movsd (Ind (Reg32 r)) (XMMReg xd) = ensureBufferSize x86_max_instruction_bytes >> x86_mov_sse_membase_reg x86_sse_sd r 0 xd++instance Movsd XMMReg (Disp, Reg32) where+    movsd (XMMReg xd) (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_mov_sse_reg_membase x86_sse_sd xd r d++instance Movsd (Disp, Reg32) XMMReg where+    movsd (Disp d, Reg32 r) (XMMReg xd) = ensureBufferSize x86_max_instruction_bytes >> x86_mov_sse_membase_reg x86_sse_sd r d xd+++class Comisd a b where+    comisd :: a -> b -> CodeGen e s ()++instance Comisd XMMReg XMMReg where+    comisd (XMMReg xd) (XMMReg xs) = ensureBufferSize x86_max_instruction_bytes >> x86_comisd_reg_reg xd xs++instance Comisd XMMReg Addr where+    comisd (XMMReg xd) (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_comisd_reg_mem xd a++instance Comisd XMMReg Ind where+    comisd (XMMReg xd) (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_comisd_reg_membase xd r 0++instance Comisd XMMReg (Disp, Reg32) where+    comisd (XMMReg xd) (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_comisd_reg_membase xd r d+++class Comiss a b where+    comiss :: a -> b -> CodeGen e s ()++instance Comiss XMMReg XMMReg where+    comiss (XMMReg xd) (XMMReg xs) = ensureBufferSize x86_max_instruction_bytes >> x86_comiss_reg_reg xd xs++instance Comiss XMMReg Addr where+    comiss (XMMReg xd) (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_comiss_reg_mem xd a++instance Comiss XMMReg Ind where+    comiss (XMMReg xd) (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_comiss_reg_membase xd r 0++instance Comiss XMMReg (Disp, Reg32) where+    comiss (XMMReg xd) (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_comiss_reg_membase xd r d+++class Ucomisd a b where+    ucomisd :: a -> b -> CodeGen e s ()++instance Ucomisd XMMReg XMMReg where+    ucomisd (XMMReg xd) (XMMReg xs) = ensureBufferSize x86_max_instruction_bytes >> x86_ucomisd_reg_reg xd xs++instance Ucomisd XMMReg Addr where+    ucomisd (XMMReg xd) (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_ucomisd_reg_mem xd a++instance Ucomisd XMMReg Ind where+    ucomisd (XMMReg xd) (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_ucomisd_reg_membase xd r 0++instance Ucomisd XMMReg (Disp, Reg32) where+    ucomisd (XMMReg xd) (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_ucomisd_reg_membase xd r d+++class Ucomiss a b where+    ucomiss :: a -> b -> CodeGen e s ()++instance Ucomiss XMMReg XMMReg where+    ucomiss (XMMReg xd) (XMMReg xs) = ensureBufferSize x86_max_instruction_bytes >> x86_ucomiss_reg_reg xd xs++instance Ucomiss XMMReg Addr where+    ucomiss (XMMReg xd) (Addr a) = ensureBufferSize x86_max_instruction_bytes >> x86_ucomiss_reg_mem xd a++instance Ucomiss XMMReg Ind where+    ucomiss (XMMReg xd) (Ind (Reg32 r)) = ensureBufferSize x86_max_instruction_bytes >> x86_ucomiss_reg_membase xd r 0++instance Ucomiss XMMReg (Disp, Reg32) where+    ucomiss (XMMReg xd) (Disp d, Reg32 r) = ensureBufferSize x86_max_instruction_bytes >> x86_ucomiss_reg_membase xd r d++
− Harpy/X86Assembler.lhs
@@ -1,2906 +0,0 @@--> ---------------------------------------------------------------------------> -- |-> -- Module      :  X86Assembler-> -- Copyright   :  (c) 2006-2007 Martin Grabmueller and Dirk Kleeblatt-> -- License     :  GPL-> -- -> -- Maintainer  :  {magr,klee}@cs.tu-berlin.de-> -- Stability   :  provisional-> -- Portability :  non-portable-> ---> -- A type class based layer on top of X86CodeGen-> -- which determines the addressing modes from the types of the-> -- operands.-> -----------------------------------------------------------------------------This module provides simple assembler facilities.--> module Harpy.X86Assembler where--> import Harpy.X86CodeGen-> import Harpy.CodeGenMonad-> import Data.Word-> import Foreign.Ptr--> import qualified Text.PrettyPrint.HughesPJ as PP---address modes used in this module:--Word8/16/32	   	     immediate values-Reg8/16/32	             register-Addr Word32		     absolut-Ind Reg32		     register indirect-(Disp, Reg32)		     register indirect with displacement-(Reg32, Reg32, Scale)	     (base, index, scale), effective address is (base + index * scale)-(Disp, Reg32, Scale)	     (disp, index, scale), effective address is (disp + index * scale)-(Disp, Reg32, Reg32, Scale)  (base, index, scale) + displacement (only ebp is allowed as base register)-Label                        not-yet-specified label- -> onlyEbp = failCodeGen (PP.text "only epb is allowed as base register for disp/base/index/scale addressing")-> onlyCl  = failCodeGen (PP.text "only cl is allowed as shift count")---x86 Registers--> newtype Reg8 = Reg8 Word8-> al, cl, dl, bl, ah, ch, dh, bh :: Reg8--> al = Reg8 0-> cl = Reg8 1-> dl = Reg8 2-> bl = Reg8 3-> ah = Reg8 4-> ch = Reg8 5-> dh = Reg8 6-> bh = Reg8 7--> newtype Reg16 = Reg16 Word8-> ax, cx, dx, bx, sp, bp, si, di :: Reg16--> ax = Reg16 0-> cx = Reg16 1-> dx = Reg16 2-> bx = Reg16 3-> sp = Reg16 4-> bp = Reg16 5-> si = Reg16 6-> di = Reg16 7--> newtype Reg32 = Reg32 Word8 deriving Eq-> eax, ecx, edx, ebx, esp, ebp, esi, edi :: Reg32--> eax = Reg32 0-> ecx = Reg32 1-> edx = Reg32 2-> ebx = Reg32 3-> esp = Reg32 4-> ebp = Reg32 5-> esi = Reg32 6-> edi = Reg32 7---- TODO: instances for other registers--> instance Show Reg32 where->  show (Reg32 0) = "eax"->  show (Reg32 1) = "ecx"->  show (Reg32 2) = "edx"->  show (Reg32 3) = "ebx"->  show (Reg32 4) = "esp"->  show (Reg32 5) = "ebp"->  show (Reg32 6) = "esi"->  show (Reg32 7) = "edi"--memory addresses--> newtype Addr  = Addr Word32-> newtype Ind   = Ind Reg32-> newtype Disp  = Disp Word32--> data    Scale = S1 | S2 | S4 | S8--> scaleToShift :: Scale -> Word8-> scaleToShift S1 = 0-> scaleToShift S2 = 1-> scaleToShift S4 = 2-> scaleToShift S8 = 3---int 3--> breakpoint = x86_breakpoint---clear direction flag--> cld = x86_cld---store string--> stosb = x86_stosb-> stosl = x86_stosl-> stosd = x86_stosd---move string--> movsb = x86_movsb-> movsl = x86_movsl-> movsd = x86_movsd---read time stamp counter--> rdtsc = x86_rdtsc---compare and exchange--> class Cmpxchg a b where->   cmpxchg :: a -> b -> CodeGen e s ()--> instance Cmpxchg Reg32 Reg32 where->   cmpxchg (Reg32 dest) (Reg32 source) = x86_cmpxchg_reg_reg dest source->-> instance Cmpxchg Addr Reg32 where->   cmpxchg (Addr dest) (Reg32 source) = x86_cmpxchg_mem_reg dest source->-> instance Cmpxchg (Disp, Reg32) Reg32 where->   cmpxchg (Disp disp, Reg32 dest) (Reg32 source) = x86_cmpxchg_membase_reg dest disp source->-> instance Cmpxchg Ind Reg32 where->   cmpxchg (Ind (Reg32 dest)) (Reg32 source) = x86_cmpxchg_membase_reg dest 0 source----exchange memory/register with register--> class Xchg a b where->   xchg :: a -> b -> CodeGen e s ()--> instance Xchg Reg8 Reg8 where->   xchg (Reg8 dest) (Reg8 source) = x86_xchg_reg_reg dest source 1->-> instance Xchg Reg32 Reg32 where->   xchg (Reg32 dest) (Reg32 source) = x86_xchg_reg_reg dest source 4->-> instance Xchg Addr Reg8 where->   xchg (Addr dest) (Reg8 source) = x86_xchg_mem_reg dest source 1->-> instance Xchg Addr Reg32 where->   xchg (Addr dest) (Reg32 source) = x86_xchg_mem_reg dest source 4->-> instance Xchg (Disp, Reg32) Reg8 where->   xchg (Disp disp, Reg32 dest) (Reg8 source) = x86_xchg_membase_reg dest disp source 1->-> instance Xchg Ind Reg8 where->   xchg (Ind (Reg32 dest)) (Reg8 source) = x86_xchg_membase_reg dest 0 source 1->-> instance Xchg (Disp, Reg32) Reg32 where->   xchg (Disp disp, Reg32 dest) (Reg32 source) = x86_xchg_membase_reg dest disp source 4->-> instance Xchg Ind Reg32 where->   xchg (Ind (Reg32 dest)) (Reg32 source) = x86_xchg_membase_reg dest 0 source 4---exchange and add--> class Xadd a b where->   xadd :: a -> b -> CodeGen e s ()--> instance Xadd Reg8 Reg8 where->   xadd (Reg8 dest) (Reg8 source) = x86_xadd_reg_reg dest source 1->-> instance Xadd Reg32 Reg32 where->   xadd (Reg32 dest) (Reg32 source) = x86_xadd_reg_reg dest source 4->-> instance Xadd Addr Reg8 where->   xadd (Addr dest) (Reg8 source) = x86_xadd_mem_reg dest source 1->-> instance Xadd Addr Reg32 where->   xadd (Addr dest) (Reg32 source) = x86_xadd_mem_reg dest source 4->-> instance Xadd (Disp, Reg32) Reg8 where->   xadd (Disp disp, Reg32 dest) (Reg8 source) = x86_xadd_membase_reg dest disp source 1->-> instance Xadd Ind Reg8 where->   xadd (Ind (Reg32 dest)) (Reg8 source) = x86_xadd_membase_reg dest 0 source 1->-> instance Xadd (Disp, Reg32) Reg32 where->   xadd (Disp disp, Reg32 dest) (Reg32 source) =  x86_xadd_membase_reg dest disp source 4->-> instance Xadd Ind Reg32 where->   xadd (Ind (Reg32 dest)) (Reg32 source) =  x86_xadd_membase_reg dest 0 source 4---Increment by 1--> class Inc a where->   inc :: a -> CodeGen e s ()--> instance Inc Addr where->   inc (Addr dest) = x86_inc_mem dest->-> instance Inc (Disp, Reg32) where->   inc (Disp disp, Reg32 dest) = x86_inc_membase dest disp->-> instance Inc Ind where->   inc (Ind (Reg32 dest)) = x86_inc_membase dest 0->-> instance Inc Reg32 where->   inc (Reg32 dest) = x86_inc_reg dest---Decrement by 1--> class Dec a where->   dec :: a -> CodeGen e s ()--> instance Dec Addr where->   dec (Addr dest) = x86_dec_mem dest->-> instance Dec (Disp, Reg32) where->   dec (Disp disp, Reg32 dest) = x86_dec_membase dest disp->-> instance Dec Ind where->   dec (Ind (Reg32 dest)) = x86_dec_membase dest 0->-> instance Dec Reg32 where->   dec (Reg32 dest) = x86_dec_reg dest---One's complement negation--> class Not a where->   not :: a -> CodeGen e s ()--> instance Not Addr where->   not (Addr dest) = x86_not_mem dest->-> instance Not (Disp, Reg32) where->   not (Disp disp, Reg32 dest) = x86_not_membase dest disp->-> instance Not Ind where->   not (Ind (Reg32 dest)) = x86_not_membase dest 0->-> instance Not Reg32 where->   not (Reg32 dest) = x86_not_reg dest---Two's complement negation--> class Neg a where->   neg :: a -> CodeGen e s ()--> instance Neg Addr where->   neg (Addr dest) = x86_neg_mem dest->-> instance Neg (Disp, Reg32) where->   neg (Disp disp, Reg32 dest) = x86_neg_membase dest disp->-> instance Neg Ind where->   neg (Ind (Reg32 dest)) = x86_neg_membase dest 0->-> instance Neg Reg32 where->   neg (Reg32 dest) = x86_neg_reg dest---No operation--> nop = x86_nop---ALU operations--Calling "x86_alu_reg8_reg8 _ _ _ *False* *False*" is a little bit hackish: the last two-arguments are set to True for the "high byte registers" ah, bh, ch and dh.-x86_reg8_emit then sets the 3rd bit in the register number. This bit is set in our-encoding anyway to the right value, so we simply skip this part.--> class Add a b where->   add :: a -> b -> CodeGen e s ()--> instance Add Reg32 Word32 where->   add (Reg32 dest) imm = x86_alu_reg_imm x86_add dest (fromIntegral imm)->-> instance Add Addr Word32 where->   add (Addr dest) imm = x86_alu_mem_imm x86_add dest (fromIntegral imm)->-> instance Add (Disp, Reg32) Word32 where->   add (Disp disp, Reg32 dest) imm = x86_alu_membase_imm x86_add dest disp (fromIntegral imm)->-> instance Add Ind Word32 where->   add (Ind (Reg32 dest)) imm = x86_alu_membase_imm x86_add dest 0 (fromIntegral imm)->-> instance Add (Disp, Reg32) Word8 where->   add (Disp disp, Reg32 dest) imm = x86_alu_membase8_imm x86_add dest disp (fromIntegral imm)->-> instance Add Ind Word8 where->   add (Ind (Reg32 dest)) imm = x86_alu_membase8_imm x86_add dest 0 (fromIntegral imm)->-> instance Add Addr Reg32 where->   add (Addr dest) (Reg32 source) = x86_alu_mem_reg x86_add dest source->-> instance Add (Disp, Reg32) Reg32 where->   add (Disp disp, Reg32 dest) (Reg32 source) = x86_alu_membase_reg x86_add dest disp source->-> instance Add Ind Reg32 where->   add (Ind (Reg32 dest)) (Reg32 source) = x86_alu_membase_reg x86_add dest 0 source->-> instance Add Reg32 Reg32 where->   add (Reg32 dest) (Reg32 source) = x86_alu_reg_reg x86_add dest source->-> instance Add Reg8 Reg8 where->   add (Reg8 dest) (Reg8 source) = x86_alu_reg8_reg8 x86_add dest source False False->-> instance Add Reg32 Addr where->   add (Reg32 dest) (Addr source) = x86_alu_reg_mem x86_add dest source->-> instance Add Reg32 (Disp, Reg32) where->   add (Reg32 dest) (Disp disp, Reg32 source) = x86_alu_reg_membase x86_add dest source disp->-> instance Add Reg32 Ind where->   add (Reg32 dest) (Ind (Reg32 source)) = x86_alu_reg_membase x86_add dest source 0---> class Or a b where->   or :: a -> b -> CodeGen e s ()--> instance Or Reg32 Word32 where->   or (Reg32 dest) imm = x86_alu_reg_imm x86_or dest (fromIntegral imm)->-> instance Or Addr Word32 where->   or (Addr dest) imm = x86_alu_mem_imm x86_or dest (fromIntegral imm)->-> instance Or (Disp, Reg32) Word32 where->   or (Disp disp, Reg32 dest) imm = x86_alu_membase_imm x86_or dest disp (fromIntegral imm)->-> instance Or Ind Word32 where->   or (Ind (Reg32 dest)) imm = x86_alu_membase_imm x86_or dest 0 (fromIntegral imm)->-> instance Or (Disp, Reg32) Word8 where->   or (Disp disp, Reg32 dest) imm = x86_alu_membase8_imm x86_or dest disp (fromIntegral imm)->-> instance Or Ind Word8 where->   or (Ind (Reg32 dest)) imm = x86_alu_membase8_imm x86_or dest 0 (fromIntegral imm)->-> instance Or Addr Reg32 where->   or (Addr dest) (Reg32 source) = x86_alu_mem_reg x86_or dest source->-> instance Or (Disp, Reg32) Reg32 where->   or (Disp disp, Reg32 dest) (Reg32 source) = x86_alu_membase_reg x86_or dest disp source->-> instance Or Ind Reg32 where->   or (Ind (Reg32 dest)) (Reg32 source) = x86_alu_membase_reg x86_or dest 0 source->-> instance Or Reg32 Reg32 where->   or (Reg32 dest) (Reg32 source) = x86_alu_reg_reg x86_or dest source->-> instance Or Reg8 Reg8 where->   or (Reg8 dest) (Reg8 source) = x86_alu_reg8_reg8 x86_or dest source False False->-> instance Or Reg32 Addr where->   or (Reg32 dest) (Addr source) = x86_alu_reg_mem x86_or dest source->-> instance Or Reg32 (Disp, Reg32) where->   or (Reg32 dest) (Disp disp, Reg32 source) = x86_alu_reg_membase x86_or dest source disp->-> instance Or Reg32 Ind where->   or (Reg32 dest) (Ind (Reg32 source)) = x86_alu_reg_membase x86_or dest source 0---> class Adc a b where->   adc :: a -> b -> CodeGen e s ()--> instance Adc Reg32 Word32 where->   adc (Reg32 dest) imm = x86_alu_reg_imm x86_adc dest (fromIntegral imm)->-> instance Adc Addr Word32 where->   adc (Addr dest) imm = x86_alu_mem_imm x86_adc dest (fromIntegral imm)->-> instance Adc (Disp, Reg32) Word32 where->   adc (Disp disp, Reg32 dest) imm = x86_alu_membase_imm x86_adc dest disp (fromIntegral imm)->-> instance Adc Ind Word32 where->   adc (Ind (Reg32 dest)) imm = x86_alu_membase_imm x86_adc dest 0 (fromIntegral imm)->-> instance Adc (Disp, Reg32) Word8 where->   adc (Disp disp, Reg32 dest) imm = x86_alu_membase8_imm x86_adc dest disp (fromIntegral imm)->-> instance Adc Ind Word8 where->   adc (Ind (Reg32 dest)) imm = x86_alu_membase8_imm x86_adc dest 0 (fromIntegral imm)->-> instance Adc Addr Reg32 where->   adc (Addr dest) (Reg32 source) = x86_alu_mem_reg x86_adc dest source->-> instance Adc (Disp, Reg32) Reg32 where->   adc (Disp disp, Reg32 dest) (Reg32 source) = x86_alu_membase_reg x86_adc dest disp source->-> instance Adc Ind Reg32 where->   adc (Ind (Reg32 dest)) (Reg32 source) = x86_alu_membase_reg x86_adc dest 0 source->-> instance Adc Reg32 Reg32 where->   adc (Reg32 dest) (Reg32 source) = x86_alu_reg_reg x86_adc dest source->-> instance Adc Reg8 Reg8 where->   adc (Reg8 dest) (Reg8 source) = x86_alu_reg8_reg8 x86_adc dest source False False->-> instance Adc Reg32 Addr where->   adc (Reg32 dest) (Addr source) = x86_alu_reg_mem x86_adc dest source->-> instance Adc Reg32 (Disp, Reg32) where->   adc (Reg32 dest) (Disp disp, Reg32 source) = x86_alu_reg_membase x86_adc dest source disp->-> instance Adc Reg32 Ind where->   adc (Reg32 dest) (Ind (Reg32 source)) = x86_alu_reg_membase x86_adc dest source 0---> class Sbb a b where->   sbb :: a -> b -> CodeGen e s ()--> instance Sbb Reg32 Word32 where->   sbb (Reg32 dest) imm = x86_alu_reg_imm x86_sbb dest (fromIntegral imm)->-> instance Sbb Addr Word32 where->   sbb (Addr dest) imm = x86_alu_mem_imm x86_sbb dest (fromIntegral imm)->-> instance Sbb (Disp, Reg32) Word32 where->   sbb (Disp disp, Reg32 dest) imm = x86_alu_membase_imm x86_sbb dest disp (fromIntegral imm)->-> instance Sbb Ind Word32 where->   sbb (Ind (Reg32 dest)) imm = x86_alu_membase_imm x86_sbb dest 0 (fromIntegral imm)->-> instance Sbb (Disp, Reg32) Word8 where->   sbb (Disp disp, Reg32 dest) imm = x86_alu_membase8_imm x86_sbb dest disp (fromIntegral imm)->-> instance Sbb Ind Word8 where->   sbb (Ind (Reg32 dest)) imm = x86_alu_membase8_imm x86_sbb dest 0 (fromIntegral imm)->-> instance Sbb Addr Reg32 where->   sbb (Addr dest) (Reg32 source) = x86_alu_mem_reg x86_sbb dest source->-> instance Sbb (Disp, Reg32) Reg32 where->   sbb (Disp disp, Reg32 dest) (Reg32 source) = x86_alu_membase_reg x86_sbb dest disp source->-> instance Sbb Ind Reg32 where->   sbb (Ind (Reg32 dest)) (Reg32 source) = x86_alu_membase_reg x86_sbb dest 0 source->-> instance Sbb Reg32 Reg32 where->   sbb (Reg32 dest) (Reg32 source) = x86_alu_reg_reg x86_sbb dest source->-> instance Sbb Reg8 Reg8 where->   sbb (Reg8 dest) (Reg8 source) = x86_alu_reg8_reg8 x86_sbb dest source False False->-> instance Sbb Reg32 Addr where->   sbb (Reg32 dest) (Addr source) = x86_alu_reg_mem x86_sbb dest source->-> instance Sbb Reg32 (Disp, Reg32) where->   sbb (Reg32 dest) (Disp disp, Reg32 source) = x86_alu_reg_membase x86_sbb dest source disp->-> instance Sbb Reg32 Ind where->   sbb (Reg32 dest) (Ind (Reg32 source)) = x86_alu_reg_membase x86_sbb dest source 0---> class And a b where->   and :: a -> b -> CodeGen e s ()--> instance And Reg32 Word32 where->   and (Reg32 dest) imm = x86_alu_reg_imm x86_and dest (fromIntegral imm)->-> instance And Addr Word32 where->   and (Addr dest) imm = x86_alu_mem_imm x86_and dest (fromIntegral imm)->-> instance And (Disp, Reg32) Word32 where->   and (Disp disp, Reg32 dest) imm = x86_alu_membase_imm x86_and dest disp (fromIntegral imm)->-> instance And Ind Word32 where->   and (Ind (Reg32 dest)) imm = x86_alu_membase_imm x86_and dest 0 (fromIntegral imm)->-> instance And (Disp, Reg32) Word8 where->   and (Disp disp, Reg32 dest) imm = x86_alu_membase8_imm x86_and dest disp (fromIntegral imm)->-> instance And Ind Word8 where->   and (Ind (Reg32 dest)) imm = x86_alu_membase8_imm x86_and dest 0 (fromIntegral imm)->-> instance And Addr Reg32 where->   and (Addr dest) (Reg32 source) = x86_alu_mem_reg x86_and dest source->-> instance And (Disp, Reg32) Reg32 where->   and (Disp disp, Reg32 dest) (Reg32 source) = x86_alu_membase_reg x86_and dest disp source->-> instance And Ind Reg32 where->   and (Ind (Reg32 dest)) (Reg32 source) = x86_alu_membase_reg x86_and dest 0 source->-> instance And Reg32 Reg32 where->   and (Reg32 dest) (Reg32 source) = x86_alu_reg_reg x86_and dest source->-> instance And Reg8 Reg8 where->   and (Reg8 dest) (Reg8 source) = x86_alu_reg8_reg8 x86_and dest source False False->-> instance And Reg32 Addr where->   and (Reg32 dest) (Addr source) = x86_alu_reg_mem x86_and dest source->-> instance And Reg32 (Disp, Reg32) where->   and (Reg32 dest) (Disp disp, Reg32 source) = x86_alu_reg_membase x86_and dest source disp->-> instance And Reg32 Ind where->   and (Reg32 dest) (Ind (Reg32 source)) = x86_alu_reg_membase x86_and dest source 0->--> class Sub a b where->   sub :: a -> b -> CodeGen e s ()--> instance Sub Reg32 Word32 where->   sub (Reg32 dest) imm = x86_alu_reg_imm x86_sub dest (fromIntegral imm)->-> instance Sub Addr Word32 where->   sub (Addr dest) imm = x86_alu_mem_reg x86_sub dest (fromIntegral imm)->-> instance Sub (Disp, Reg32) Word32 where->   sub (Disp disp, Reg32 dest) imm = x86_alu_membase_imm x86_sub dest disp (fromIntegral imm)->-> instance Sub Ind Word32 where->   sub (Ind (Reg32 dest)) imm = x86_alu_membase_imm x86_sub dest 0 (fromIntegral imm)->-> instance Sub (Disp, Reg32) Word8 where->   sub (Disp disp, Reg32 dest) imm = x86_alu_membase8_imm x86_sub dest disp (fromIntegral imm)->-> instance Sub Ind Word8 where->   sub (Ind (Reg32 dest)) imm = x86_alu_membase8_imm x86_sub dest 0 (fromIntegral imm)->-> instance Sub Addr Reg32 where->   sub (Addr dest) (Reg32 source) = x86_alu_mem_reg x86_sub dest source->-> instance Sub (Disp, Reg32) Reg32 where->   sub (Disp disp, Reg32 dest) (Reg32 source) = x86_alu_membase_reg x86_sub dest disp source->-> instance Sub Ind Reg32 where->   sub (Ind (Reg32 dest)) (Reg32 source) = x86_alu_membase_reg x86_sub dest 0 source->-> instance Sub Reg32 Reg32 where->   sub (Reg32 dest) (Reg32 source) = x86_alu_reg_reg x86_sub dest source->-> instance Sub Reg8 Reg8 where->   sub (Reg8 dest) (Reg8 source) = x86_alu_reg8_reg8 x86_sub dest source False False->-> instance Sub Reg32 Addr where->   sub (Reg32 dest) (Addr source) = x86_alu_reg_mem x86_sub dest source->-> instance Sub Reg32 (Disp, Reg32) where->   sub (Reg32 dest) (Disp disp, Reg32 source) = x86_alu_reg_membase x86_sub dest source disp->-> instance Sub Reg32 Ind where->   sub (Reg32 dest) (Ind (Reg32 source)) = x86_alu_reg_membase x86_sub dest source 0---> class Xor a b where->   xor :: a -> b -> CodeGen e s ()--> instance Xor Reg32 Word32 where->   xor (Reg32 dest) imm = x86_alu_reg_imm x86_xor dest (fromIntegral imm)->-> instance Xor Addr Word32 where->   xor (Addr dest) imm = x86_alu_mem_imm x86_xor dest (fromIntegral imm)->-> instance Xor (Disp, Reg32) Word32 where->   xor (Disp disp, Reg32 dest) imm = x86_alu_membase_imm x86_xor dest disp (fromIntegral imm)->-> instance Xor Ind Word32 where->   xor (Ind (Reg32 dest)) imm = x86_alu_membase_imm x86_xor dest 0 (fromIntegral imm)->-> instance Xor (Disp, Reg32) Word8 where->   xor (Disp disp, Reg32 dest) imm = x86_alu_membase8_imm x86_xor dest disp (fromIntegral imm)->-> instance Xor Ind Word8 where->   xor (Ind (Reg32 dest)) imm = x86_alu_membase8_imm x86_xor dest 0 (fromIntegral imm)->-> instance Xor Addr Reg32 where->   xor (Addr dest) (Reg32 source) = x86_alu_mem_reg x86_xor dest source->-> instance Xor (Disp, Reg32) Reg32 where->   xor (Disp disp, Reg32 dest) (Reg32 source) = x86_alu_membase_reg x86_xor dest disp source->-> instance Xor Ind Reg32 where->   xor (Ind (Reg32 dest)) (Reg32 source) = x86_alu_membase_reg x86_xor dest 0 source->-> instance Xor Reg32 Reg32 where->   xor (Reg32 dest) (Reg32 source) = x86_alu_reg_reg x86_xor dest source->-> instance Xor Reg8 Reg8 where->   xor (Reg8 dest) (Reg8 source) = x86_alu_reg8_reg8 x86_xor dest source False False->-> instance Xor Reg32 Addr where->   xor (Reg32 dest) (Addr source) = x86_alu_reg_mem x86_xor dest source->-> instance Xor Reg32 (Disp, Reg32) where->   xor (Reg32 dest) (Disp disp, Reg32 source) = x86_alu_reg_membase x86_xor dest source disp->-> instance Xor Reg32 Ind where->   xor (Reg32 dest) (Ind (Reg32 source)) = x86_alu_reg_membase x86_xor dest source 0---> class Cmp a b where->   cmp :: a -> b -> CodeGen e s ()--> instance Cmp Reg32 Word32 where->   cmp (Reg32 dest) imm = x86_alu_reg_imm x86_cmp dest (fromIntegral imm)->-> instance Cmp Reg32 Label where->   cmp (Reg32 dest) lab = do->       x86_alu_reg_imm x86_cmp dest 0xf0f0f0f0->       emitFixup lab (-4) Fixup32Absolute->-> instance Cmp Addr Word32 where->   cmp (Addr dest) imm = x86_alu_mem_imm x86_cmp dest (fromIntegral imm)->-> instance Cmp Addr Label where->   cmp (Addr dest) lab = do->       x86_alu_mem_imm x86_cmp dest 0xf0f0f0f0->       emitFixup lab (-4) Fixup32Absolute->-> instance Cmp (Disp, Reg32) Word32 where->   cmp (Disp disp, Reg32 dest) imm = x86_alu_membase_imm x86_cmp dest disp (fromIntegral imm)->-> instance Cmp (Disp, Reg32) Label where->   cmp (Disp disp, Reg32 dest) lab = do->                                    x86_alu_membase_imm x86_cmp dest disp 0xf0f0f0f0->                                    emitFixup lab (-4) Fixup32Absolute->-> instance Cmp Ind Word32 where->   cmp (Ind (Reg32 dest)) imm = x86_alu_membase_imm x86_cmp dest 0 (fromIntegral imm)->-> instance Cmp Ind Label where->   cmp (Ind (Reg32 dest)) lab = do->                          x86_alu_membase_imm x86_cmp dest 0 0xf0f0f0f0->                          emitFixup lab (-4) Fixup32Absolute->-> instance Cmp (Disp, Reg32) Word8 where->   cmp (Disp disp, Reg32 dest) imm = x86_alu_membase8_imm x86_cmp dest disp imm->-> instance Cmp Ind Word8 where->   cmp (Ind (Reg32 dest)) imm = x86_alu_membase8_imm x86_cmp dest 0 imm->-> instance Cmp Addr Reg32 where->   cmp (Addr dest) (Reg32 source) = x86_alu_mem_reg x86_cmp dest source->-> instance Cmp (Disp, Reg32) Reg32 where->   cmp (Disp disp, Reg32 dest) (Reg32 source) = x86_alu_membase_reg x86_cmp dest disp source->-> instance Cmp Ind Reg32 where->   cmp (Ind (Reg32 dest)) (Reg32 source) = x86_alu_membase_reg x86_cmp dest 0 source->-> instance Cmp Reg32 Reg32 where->   cmp (Reg32 dest) (Reg32 source) = x86_alu_reg_reg x86_cmp dest source->-> instance Cmp Reg8 Reg8 where->   cmp (Reg8 dest) (Reg8 source) = x86_alu_reg8_reg8 x86_cmp dest source False False->-> instance Cmp Reg32 Addr where->   cmp (Reg32 dest) (Addr source) = x86_alu_reg_mem x86_cmp dest source->-> instance Cmp Reg32 (Disp, Reg32) where->   cmp (Reg32 dest) (Disp disp, Reg32 source) = x86_alu_reg_membase x86_cmp dest source disp->-> instance Cmp Reg32 Ind where->   cmp (Reg32 dest) (Ind (Reg32 source)) = x86_alu_reg_membase x86_cmp dest source 0---logical compare--> class Test a b where->   test :: a -> b -> CodeGen e s ()--> instance Test Reg32 Word32 where->   test (Reg32 dest) imm = x86_test_reg_imm dest imm ->-> instance Test Addr Word32 where->   test (Addr dest) imm = x86_test_mem_imm dest imm ->-> instance Test (Disp, Reg32) Word32 where->   test (Disp disp, Reg32 dest) imm = x86_test_membase_imm dest disp imm ->-> instance Test Ind Word32 where->   test (Ind (Reg32 dest)) imm = x86_test_membase_imm dest 0 imm ->-> instance Test Reg32 Reg32 where->   test (Reg32 dest) (Reg32 source) = x86_test_reg_reg dest source ->-> instance Test Addr Reg32 where->   test (Addr dest) (Reg32 source) = x86_test_mem_reg dest source ->-> instance Test (Disp, Reg32) Reg32 where->   test (Disp disp, Reg32 dest) (Reg32 source) = x86_test_membase_reg dest disp source ->-> instance Test Ind Reg32 where->   test (Ind (Reg32 dest)) (Reg32 source) = x86_test_membase_reg dest 0 source ---shift and rotate--> class Rol a b where->   rol :: a -> b -> CodeGen e s ()->-> instance Rol Reg32 Word8 where->   rol (Reg32 dest) imm = x86_shift_reg_imm x86_rol dest imm ->-> instance Rol Addr Word8 where->   rol (Addr dest) imm = x86_shift_mem_imm x86_rol dest imm ->-> instance Rol (Disp, Reg32) Word8 where->   rol (Disp disp, Reg32 dest) imm = x86_shift_membase_imm x86_rol dest disp imm ->-> instance Rol Ind Word8 where->   rol (Ind (Reg32 dest)) imm = x86_shift_membase_imm x86_rol dest 0 imm ->-> instance Rol Reg32 Reg8 where->   rol (Reg32 dest) (Reg8 1) = x86_shift_reg x86_rol dest->   rol _ _ = onlyCl->-> instance Rol Addr Reg8 where->   rol (Addr dest) (Reg8 1) = x86_shift_mem x86_rol dest->   rol _ _ = onlyCl->-> instance Rol (Disp, Reg32) Reg8 where->   rol (Disp disp, Reg32 dest) (Reg8 1) = x86_shift_membase x86_rol dest disp->-> instance Rol Ind Reg8 where->   rol (Ind (Reg32 dest)) (Reg8 1) = x86_shift_membase x86_rol dest 0->   rol _ _ = onlyCl--> class Ror a b where->   ror :: a -> b -> CodeGen e s ()->-> instance Ror Reg32 Word8 where->   ror (Reg32 dest) imm = x86_shift_reg_imm x86_ror dest imm ->-> instance Ror Addr Word8 where->   ror (Addr dest) imm = x86_shift_mem_imm x86_ror dest imm ->-> instance Ror (Disp, Reg32) Word8 where->   ror (Disp disp, Reg32 dest) imm = x86_shift_membase_imm x86_ror dest disp imm ->-> instance Ror Ind Word8 where->   ror (Ind (Reg32 dest)) imm = x86_shift_membase_imm x86_ror dest 0 imm ->-> instance Ror Reg32 Reg8 where->   ror (Reg32 dest) (Reg8 1) = x86_shift_reg x86_ror dest->   ror _ _ = onlyCl->-> instance Ror Addr Reg8 where->   ror (Addr dest) (Reg8 1) = x86_shift_mem x86_ror dest->   ror _ _ = onlyCl->-> instance Ror (Disp, Reg32) Reg8 where->   ror (Disp disp, Reg32 dest) (Reg8 1) = x86_shift_membase x86_ror dest disp->-> instance Ror Ind Reg8 where->   ror (Ind (Reg32 dest)) (Reg8 1) = x86_shift_membase x86_ror dest 0->   ror _ _ = onlyCl--> class Rcl a b where->   rcl :: a -> b -> CodeGen e s ()->-> instance Rcl Reg32 Word8 where->   rcl (Reg32 dest) imm = x86_shift_reg_imm x86_rcl dest imm ->-> instance Rcl Addr Word8 where->   rcl (Addr dest) imm = x86_shift_mem_imm x86_rcl dest imm ->-> instance Rcl (Disp, Reg32) Word8 where->   rcl (Disp disp, Reg32 dest) imm = x86_shift_membase_imm x86_rcl dest disp imm ->-> instance Rcl Ind Word8 where->   rcl (Ind (Reg32 dest)) imm = x86_shift_membase_imm x86_rcl dest 0 imm ->-> instance Rcl Reg32 Reg8 where->   rcl (Reg32 dest) (Reg8 1) = x86_shift_reg x86_rcl dest->   rcl _ _ = onlyCl->-> instance Rcl Addr Reg8 where->   rcl (Addr dest) (Reg8 1) = x86_shift_mem x86_rcl dest->   rcl _ _ = onlyCl->-> instance Rcl (Disp, Reg32) Reg8 where->   rcl (Disp disp, Reg32 dest) (Reg8 1) = x86_shift_membase x86_rcl dest disp->-> instance Rcl Ind Reg8 where->   rcl (Ind (Reg32 dest)) (Reg8 1) = x86_shift_membase x86_rcl dest 0->   rcl _ _ = onlyCl--> class Rcr a b where->   rcr :: a -> b -> CodeGen e s ()->-> instance Rcr Reg32 Word8 where->   rcr (Reg32 dest) imm = x86_shift_reg_imm x86_rcr dest imm ->-> instance Rcr Addr Word8 where->   rcr (Addr dest) imm = x86_shift_mem_imm x86_rcr dest imm ->-> instance Rcr (Disp, Reg32) Word8 where->   rcr (Disp disp, Reg32 dest) imm = x86_shift_membase_imm x86_rcr dest disp imm ->-> instance Rcr Ind Word8 where->   rcr (Ind (Reg32 dest)) imm = x86_shift_membase_imm x86_rcr dest 0 imm ->-> instance Rcr Reg32 Reg8 where->   rcr (Reg32 dest) (Reg8 1) = x86_shift_reg x86_rcr dest->   rcr _ _ = onlyCl->-> instance Rcr Addr Reg8 where->   rcr (Addr dest) (Reg8 1) = x86_shift_mem x86_rcr dest->   rcr _ _ = onlyCl->-> instance Rcr (Disp, Reg32) Reg8 where->   rcr (Disp disp, Reg32 dest) (Reg8 1) = x86_shift_membase x86_rcr dest disp->-> instance Rcr Ind Reg8 where->   rcr (Ind (Reg32 dest)) (Reg8 1) = x86_shift_membase x86_rcr dest 0->   rcr _ _ = onlyCl--> class Shl a b where->   shl :: a -> b -> CodeGen e s ()->-> instance Shl Reg32 Word8 where->   shl (Reg32 dest) imm = x86_shift_reg_imm x86_shl dest imm ->-> instance Shl Addr Word8 where->   shl (Addr dest) imm = x86_shift_mem_imm x86_shl dest imm ->-> instance Shl (Disp, Reg32) Word8 where->   shl (Disp disp, Reg32 dest) imm = x86_shift_membase_imm x86_shl dest disp imm ->-> instance Shl Ind Word8 where->   shl (Ind (Reg32 dest)) imm = x86_shift_membase_imm x86_shl dest 0 imm ->-> instance Shl Reg32 Reg8 where->   shl (Reg32 dest) (Reg8 1) = x86_shift_reg x86_shl dest->   shl _ _ = onlyCl->-> instance Shl Addr Reg8 where->   shl (Addr dest) (Reg8 1) = x86_shift_mem x86_shl dest->   shl _ _ = onlyCl->-> instance Shl (Disp, Reg32) Reg8 where->   shl (Disp disp, Reg32 dest) (Reg8 1) = x86_shift_membase x86_shl dest disp->-> instance Shl Ind Reg8 where->   shl (Ind (Reg32 dest)) (Reg8 1) = x86_shift_membase x86_shl dest 0->   shl _ _ = onlyCl--> class Shr a b where->   shr :: a -> b -> CodeGen e s ()->-> instance Shr Reg32 Word8 where->   shr (Reg32 dest) imm = x86_shift_reg_imm x86_shr dest imm ->-> instance Shr Addr Word8 where->   shr (Addr dest) imm = x86_shift_mem_imm x86_shr dest imm ->-> instance Shr (Disp, Reg32) Word8 where->   shr (Disp disp, Reg32 dest) imm = x86_shift_membase_imm x86_shr dest disp imm ->-> instance Shr Ind Word8 where->   shr (Ind (Reg32 dest)) imm = x86_shift_membase_imm x86_shr dest 0 imm ->-> instance Shr Reg32 Reg8 where->   shr (Reg32 dest) (Reg8 1) = x86_shift_reg x86_shr dest->   shr _ _ = onlyCl->-> instance Shr Addr Reg8 where->   shr (Addr dest) (Reg8 1) = x86_shift_mem x86_shr dest->   shr _ _ = onlyCl->-> instance Shr (Disp, Reg32) Reg8 where->   shr (Disp disp, Reg32 dest) (Reg8 1) = x86_shift_membase x86_shr dest disp->-> instance Shr Ind Reg8 where->   shr (Ind (Reg32 dest)) (Reg8 1) = x86_shift_membase x86_shr dest 0->   shr _ _ = onlyCl--> class Sar a b where->   sar :: a -> b -> CodeGen e s ()->-> instance Sar Reg32 Word8 where->   sar (Reg32 dest) imm = x86_shift_reg_imm x86_sar dest imm ->-> instance Sar Addr Word8 where->   sar (Addr dest) imm = x86_shift_mem_imm x86_sar dest imm ->-> instance Sar (Disp, Reg32) Word8 where->   sar (Disp disp, Reg32 dest) imm = x86_shift_membase_imm x86_sar dest disp imm ->-> instance Sar Ind Word8 where->   sar (Ind (Reg32 dest)) imm = x86_shift_membase_imm x86_sar dest 0 imm ->-> instance Sar Reg32 Reg8 where->   sar (Reg32 dest) (Reg8 1) = x86_shift_reg x86_sar dest->   sar _ _ = onlyCl->-> instance Sar Addr Reg8 where->   sar (Addr dest) (Reg8 1) = x86_shift_mem x86_sar dest->   sar _ _ = onlyCl->-> instance Sar (Disp, Reg32) Reg8 where->   sar (Disp disp, Reg32 dest) (Reg8 1) = x86_shift_membase x86_sar dest disp->-> instance Sar Ind Reg8 where->   sar (Ind (Reg32 dest)) (Reg8 1) = x86_shift_membase x86_sar dest 0->   sar _ _ = onlyCl--> class Sal a b where->   sal :: a -> b -> CodeGen e s ()->-> instance Sal Reg32 Word8 where->   sal (Reg32 dest) imm = x86_shift_reg_imm x86_shl dest imm ->-> instance Sal Addr Word8 where->   sal (Addr dest) imm = x86_shift_mem_imm x86_shl dest imm ->-> instance Sal (Disp, Reg32) Word8 where->   sal (Disp disp, Reg32 dest) imm = x86_shift_membase_imm x86_shl dest disp imm ->-> instance Sal Ind Word8 where->   sal (Ind (Reg32 dest)) imm = x86_shift_membase_imm x86_shl dest 0 imm ->-> instance Sal Reg32 Reg8 where->   sal (Reg32 dest) (Reg8 1) = x86_shift_reg x86_shl dest->   sal _ _ = onlyCl->-> instance Sal Addr Reg8 where->   sal (Addr dest) (Reg8 1) = x86_shift_mem x86_shl dest->   sal _ _ = onlyCl->-> instance Sal (Disp, Reg32) Reg8 where->   sal (Disp disp, Reg32 dest) (Reg8 1) = x86_shift_membase x86_shl dest disp->-> instance Sal Ind Reg8 where->   sal (Ind (Reg32 dest)) (Reg8 1) = x86_shift_membase x86_shl dest 0->   sal _ _ = onlyCl---double precision shift right--> class Shrd a b c where->   shrd :: a -> b -> c -> CodeGen e s ()--> instance Shrd Reg32 Reg32 Reg8 where->   shrd (Reg32 dest) (Reg32 source) (Reg8 1) = x86_shrd_reg dest source->   shrd _ _ _ = onlyCl->-> instance Shrd Reg32 Reg32 Word8 where->   shrd (Reg32 dest) (Reg32 source) imm = x86_shrd_reg_imm dest source imm ---double precision shift left--> class Shld a b c where->   shld :: a -> b -> c -> CodeGen e s ()--> instance Shld Reg32 Reg32 Reg8 where->   shld (Reg32 dest) (Reg32 source) (Reg8 1) = x86_shld_reg dest source->   shld _ _ _ = onlyCl->-> instance Shld Reg32 Reg32 Word8 where->   shld (Reg32 dest) (Reg32 source) imm = x86_shld_reg_imm dest source imm ---unsigned multiply--> class Mul a where->   mul :: a -> CodeGen e s ()--> instance Mul Reg32 where->   mul (Reg32 arg) = x86_mul_reg arg False->-> instance Mul Addr where->   mul (Addr arg) = x86_mul_mem arg False->-> instance Mul (Disp, Reg32) where->   mul (Disp disp, Reg32 arg) = x86_mul_membase arg disp False->-> instance Mul Ind where->   mul (Ind (Reg32 arg)) = x86_mul_membase arg 0 False---signed multiply--> data InPlace = InPlace--if a == InPlace then-  b = b * c-else-  a = b * c--> class Imul a b c where->   imul :: a -> b -> c -> CodeGen e s ()--> instance Imul InPlace Reg32 Reg32 where->   imul _ (Reg32 dest) (Reg32 source) = x86_imul_reg_reg dest source->-> instance Imul InPlace Reg32 Addr where->   imul _ (Reg32 dest) (Addr source) = x86_imul_reg_mem dest source->-> instance Imul InPlace Reg32 (Disp, Reg32) where->   imul _ (Reg32 dest) (Disp disp, Reg32 source) = x86_imul_reg_membase dest source disp->-> instance Imul InPlace Reg32 Ind where->   imul _ (Reg32 dest) (Ind (Reg32 source)) = x86_imul_reg_membase dest source 0->-> instance Imul Reg32 Reg32 Word32 where->   imul (Reg32 dest) (Reg32 source) imm = x86_imul_reg_reg_imm dest source imm ->-> instance Imul Reg32 Addr Word32 where->   imul (Reg32 dest) (Addr source) imm = x86_imul_reg_mem_imm dest source imm ->-> instance Imul Reg32 (Disp, Reg32) Word32 where->   imul (Reg32 dest) (Disp disp, Reg32 source) imm = x86_imul_reg_membase_imm dest source disp imm ->-> instance Imul Reg32 Ind Word32 where->   imul (Reg32 dest) (Ind (Reg32 source)) imm = x86_imul_reg_membase_imm dest source 0 imm ---divide EDX:EAX by rm;-eax = quotient, edx = remainder--unsigned divide--> class Div a where->   div :: a -> CodeGen e s ()--> instance Div Reg32 where->   div (Reg32 arg) = x86_div_reg arg False->-> instance Div Addr where->   div (Addr arg) = x86_div_mem arg False->-> instance Div (Disp, Reg32) where->   div (Disp disp, Reg32 arg) = x86_div_membase arg disp False->-> instance Div Ind where->   div (Ind (Reg32 arg)) = x86_div_membase arg 0 False---signed divide--> class Idiv a where->   idiv :: a -> CodeGen e s ()--> instance Idiv Reg32 where->   idiv (Reg32 arg) = x86_div_reg arg True->-> instance Idiv Addr where->   idiv (Addr arg) = x86_div_mem arg True->-> instance Idiv (Disp, Reg32) where->   idiv (Disp disp, Reg32 arg) = x86_div_membase arg disp True->-> instance Idiv Ind where->   idiv (Ind (Reg32 arg)) = x86_div_membase arg 0 True---"mov" instruction for different sources and destinations--> class Mov a b where->   mov :: a -> b -> CodeGen e s ()---> instance Mov Reg8 Reg8 where->   mov (Reg8 dest) (Reg8 source) = x86_mov_reg_reg dest source 1->-> instance Mov Reg16 Reg16 where->   mov (Reg16 dest) (Reg16 source) = x86_mov_reg_reg dest source 2->-> instance Mov Reg32 Reg32 where->   mov (Reg32 dest) (Reg32 source) = x86_mov_reg_reg dest source 4---> instance Mov Reg32 Word32 where->   mov (Reg32 dest) imm = x86_mov_reg_imm dest (fromIntegral imm)--> instance Mov Reg32 Label where->   mov (Reg32 dest) lab = do x86_mov_reg_imm dest 0->                             emitFixup lab (-4) Fixup32Absolute--> instance Mov Addr Word8 where->   mov (Addr dest) imm = x86_mov_mem_imm dest (fromIntegral imm) 1->-> instance Mov Addr Word16 where->   mov (Addr dest) imm = x86_mov_mem_imm dest (fromIntegral imm) 2->-> instance Mov Addr Word32 where->   mov (Addr dest) imm = x86_mov_mem_imm dest imm 4--> instance Mov Addr Label where->   mov (Addr dest) lab = do x86_mov_mem_imm dest 0 4->                            emitFixup lab (-4) Fixup32Absolute--> instance Mov (Disp, Reg32) Word8 where->   mov (Disp disp, Reg32 dest) imm = x86_mov_membase_imm dest disp (fromIntegral imm) 1->-> instance Mov Ind Word8 where->   mov (Ind (Reg32 dest)) imm = x86_mov_membase_imm dest 0 (fromIntegral imm) 1->-> instance Mov (Disp, Reg32) Word16 where->   mov (Disp disp, Reg32 dest) imm = x86_mov_membase_imm dest disp (fromIntegral imm) 2->-> instance Mov Ind Word16 where->   mov (Ind (Reg32 dest)) imm = x86_mov_membase_imm dest 0 (fromIntegral imm) 2->-> instance Mov (Disp, Reg32) Word32 where->   mov (Disp disp, Reg32 dest) imm = x86_mov_membase_imm dest disp imm 4->-> instance Mov (Disp, Reg32) Label where->   mov (Disp disp, Reg32 dest) lab = do x86_mov_membase_imm dest disp 0 4->                                        emitFixup lab (-4) Fixup32Absolute--> instance Mov Ind Word32 where->   mov (Ind (Reg32 dest)) imm = x86_mov_membase_imm dest 0 imm 4--> instance Mov Ind Label where->   mov (Ind (Reg32 dest)) lab = do x86_mov_membase_imm dest 0 0 4->                                   emitFixup lab (-4) Fixup32Absolute--> instance Mov (Reg32, Reg32, Scale) Word8 where->   mov (Reg32 base, Reg32 index, scale) imm = x86_mov_memindex_imm base 0 index (scaleToShift scale) (fromIntegral imm) 1->-> instance Mov (Reg32, Reg32, Scale) Word16 where->   mov (Reg32 base, Reg32 index, scale) imm = x86_mov_memindex_imm base 0 index (scaleToShift scale) (fromIntegral imm) 2->-> instance Mov (Reg32, Reg32, Scale) Word32 where->   mov (Reg32 base, Reg32 index, scale) imm = x86_mov_memindex_imm base 0 index (scaleToShift scale) imm 4--> instance Mov (Reg32, Reg32, Scale) Label where->   mov (Reg32 base, Reg32 index, scale) lab = do x86_mov_memindex_imm base 0 index (scaleToShift scale) 0 4->                                                 emitFixup lab (-4) Fixup32Absolute--> instance Mov (Disp, Reg32, Scale) Word8 where->   mov (Disp disp, Reg32 index, scale) imm = x86_mov_memindex_imm x86_nobasereg disp index (scaleToShift scale) (fromIntegral imm) 1->-> instance Mov (Disp, Reg32, Scale) Word16 where->   mov (Disp disp, Reg32 index, scale) imm = x86_mov_memindex_imm x86_nobasereg disp index (scaleToShift scale) (fromIntegral imm) 2->-> instance Mov (Disp, Reg32, Scale) Word32 where->   mov (Disp disp, Reg32 index, scale) imm = x86_mov_memindex_imm x86_nobasereg disp index (scaleToShift scale) imm 4--> instance Mov (Disp, Reg32, Scale) Label where->   mov (Disp disp, Reg32 index, scale) lab = do x86_mov_memindex_imm x86_nobasereg disp index (scaleToShift scale) 0 4->                                                emitFixup lab (-4) Fixup32Absolute--> instance Mov (Disp, Reg32, Reg32, Scale) Word8 where->   mov (Disp disp, Reg32 5, Reg32 index, scale) imm = x86_mov_memindex_imm 5 disp index (scaleToShift scale) (fromIntegral imm) 1->   mov _ _ = onlyEbp->-> instance Mov (Disp, Reg32, Reg32, Scale) Word16 where->   mov (Disp disp, Reg32 5, Reg32 index, scale) imm = x86_mov_memindex_imm 5 disp index (scaleToShift scale) (fromIntegral imm) 2->   mov _ _ = onlyEbp->-> instance Mov (Disp, Reg32, Reg32, Scale) Word32 where->   mov (Disp disp, Reg32 5, Reg32 index, scale) imm = x86_mov_memindex_imm 5 disp index (scaleToShift scale) imm 4->   mov _ _ = onlyEbp--> instance Mov (Disp, Reg32, Reg32, Scale) Label where->   mov (Disp disp, Reg32 5, Reg32 index, scale) lab = do x86_mov_memindex_imm 5 disp index (scaleToShift scale) 0 4->                                                         emitFixup lab (-4) Fixup32Absolute->   mov _ _ = onlyEbp--> instance Mov Addr Reg8 where->   mov (Addr a) (Reg8 source) = x86_mov_mem_reg a source 1->-> instance Mov Addr Reg16 where->   mov (Addr a) (Reg16 source) = x86_mov_mem_reg a source 2->-> instance Mov Addr Reg32 where->   mov (Addr a) (Reg32 source) = x86_mov_mem_reg a source 4->-> instance Mov Reg8 Addr where->   mov (Reg8 dest) (Addr a) = x86_mov_reg_mem dest a 1->-> instance Mov Reg16 Addr where->   mov (Reg16 dest) (Addr a) = x86_mov_reg_mem dest a 2->-> instance Mov Reg32 Addr where->   mov (Reg32 dest) (Addr a) = x86_mov_reg_mem dest a 4---> instance Mov Ind Reg8 where->   mov (Ind (Reg32 dest)) (Reg8 source) = x86_mov_regp_reg dest source 1->-> instance Mov Ind Reg16 where->   mov (Ind (Reg32 dest)) (Reg16 source) = x86_mov_regp_reg dest source 2->-> instance Mov Ind Reg32 where->   mov (Ind (Reg32 dest)) (Reg32 source) = x86_mov_regp_reg dest source 4--> instance Mov Reg8 Ind where->   mov (Reg8 dest) (Ind (Reg32 source)) = x86_mov_reg_regp dest source 1->-> instance Mov Reg16 Ind where->   mov (Reg16 dest) (Ind (Reg32 source)) = x86_mov_reg_regp dest source 2->-> instance Mov Reg32 Ind where->   mov (Reg32 dest) (Ind (Reg32 source)) = x86_mov_reg_regp dest source 4---> instance Mov (Disp, Reg32) Reg8 where->   mov (Disp disp, Reg32 dest) (Reg8 source) = x86_mov_membase_reg dest disp source 1->-> instance Mov (Disp, Reg32) Reg16 where->   mov (Disp disp, Reg32 dest) (Reg16 source) = x86_mov_membase_reg dest disp source 2->-> instance Mov (Disp, Reg32) Reg32 where->   mov (Disp disp, Reg32 dest) (Reg32 source) = x86_mov_membase_reg dest disp source 4->-> instance Mov Reg8 (Disp, Reg32) where->   mov (Reg8 dest) (Disp disp, Reg32 source) = x86_mov_reg_membase dest source disp 1->-> instance Mov Reg16 (Disp, Reg32) where->   mov (Reg16 dest) (Disp disp, Reg32 source) = x86_mov_reg_membase dest source disp 2->-> instance Mov Reg32 (Disp, Reg32) where->   mov (Reg32 dest) (Disp disp, Reg32 source) = x86_mov_reg_membase dest source disp 4---> instance Mov (Reg32, Reg32, Scale) Reg8 where->   mov (Reg32 base, Reg32 index, s) (Reg8 source) = x86_mov_memindex_reg base 0 index (scaleToShift s) source 1->-> instance Mov (Reg32, Reg32, Scale) Reg16 where->   mov (Reg32 base, Reg32 index, s) (Reg16 source) = x86_mov_memindex_reg base 0 index (scaleToShift s) source 2->-> instance Mov (Reg32, Reg32, Scale) Reg32 where->   mov (Reg32 base, Reg32 index, s) (Reg32 source) = x86_mov_memindex_reg base 0 index (scaleToShift s) source 4->-> instance Mov Reg8 (Reg32, Reg32, Scale) where->   mov (Reg8 dest) (Reg32 base, Reg32 index, s) = x86_mov_reg_memindex dest base 0 index (scaleToShift s) 1->-> instance Mov Reg16 (Reg32, Reg32, Scale) where->   mov (Reg16 dest) (Reg32 base, Reg32 index, s) = x86_mov_reg_memindex dest base 0 index (scaleToShift s) 2->-> instance Mov Reg32 (Reg32, Reg32, Scale) where->   mov (Reg32 dest) (Reg32 base, Reg32 index, s) = x86_mov_reg_memindex dest base 0 index (scaleToShift s) 4---> instance Mov (Disp, Reg32, Scale) Reg8 where->   mov (Disp disp, Reg32 index, s) (Reg8 source) = x86_mov_memindex_reg x86_nobasereg disp index (scaleToShift s) source 1->-> instance Mov (Disp, Reg32, Scale) Reg16 where->   mov (Disp disp, Reg32 index, s) (Reg16 source) = x86_mov_memindex_reg x86_nobasereg disp index (scaleToShift s) source 2->-> instance Mov (Disp, Reg32, Scale) Reg32 where->   mov (Disp disp, Reg32 index, s) (Reg32 source) = x86_mov_memindex_reg x86_nobasereg disp index (scaleToShift s) source 4->-> instance Mov Reg8 (Disp, Reg32, Scale) where->   mov (Reg8 dest) (Disp disp, Reg32 index, s) = x86_mov_reg_memindex dest x86_nobasereg disp index (scaleToShift s) 1->-> instance Mov Reg16 (Disp, Reg32, Scale) where->   mov (Reg16 dest) (Disp disp, Reg32 index, s) = x86_mov_reg_memindex dest x86_nobasereg disp index (scaleToShift s) 2->-> instance Mov Reg32 (Disp, Reg32, Scale) where->   mov (Reg32 dest) (Disp disp, Reg32 index, s) = x86_mov_reg_memindex dest x86_nobasereg disp index (scaleToShift s) 4---> instance Mov (Disp, Reg32, Reg32, Scale) Reg8 where->   mov (Disp disp, Reg32 5, Reg32 index, s) (Reg8 source) = x86_mov_memindex_reg 5 disp index (scaleToShift s) source 1->   mov _ _ = onlyEbp->-> instance Mov (Disp, Reg32, Reg32, Scale) Reg16 where->   mov (Disp disp, Reg32 5, Reg32 index, s) (Reg16 source) = x86_mov_memindex_reg 5 disp index (scaleToShift s) source 2->   mov _ _ = onlyEbp->-> instance Mov (Disp, Reg32, Reg32, Scale) Reg32 where->   mov (Disp disp, Reg32 5, Reg32 index, s) (Reg32 source) = x86_mov_memindex_reg 5 disp index (scaleToShift s) source 4->   mov _ _ = onlyEbp->-> instance Mov Reg8 (Disp, Reg32, Reg32, Scale) where->   mov (Reg8 dest) (Disp disp, Reg32 5, Reg32 index, s) = x86_mov_reg_memindex dest 5 disp index (scaleToShift s) 1->   mov _ _ = onlyEbp->-> instance Mov Reg16 (Disp, Reg32, Reg32, Scale) where->   mov (Reg16 dest) (Disp disp, Reg32 5, Reg32 index, s) = x86_mov_reg_memindex dest 5 disp index (scaleToShift s) 2->   mov _ _ = onlyEbp->-> instance Mov Reg32 (Disp, Reg32, Reg32, Scale) where->   mov (Reg32 dest) (Disp disp, Reg32 5, Reg32 index, s) = x86_mov_reg_memindex dest 5 disp index (scaleToShift s) 4->   mov _ _ = onlyEbp---move with sign-extension--> class Movsxb a b where->   movsxb :: a -> b -> CodeGen e s ()--> instance Movsxb Reg32 Reg8 where->   movsxb (Reg32 dest) (Reg8 source) = x86_widen_reg dest source True False->-> instance Movsxb Reg32 Addr where->   movsxb (Reg32 dest) (Addr source) = x86_widen_mem dest source True False->-> instance Movsxb Reg32 (Disp, Reg32) where->   movsxb (Reg32 dest) (Disp disp, Reg32 source) = x86_widen_membase dest source disp True False->-> instance Movsxb Reg32 Ind where->   movsxb (Reg32 dest) (Ind (Reg32 source)) = x86_widen_membase dest source 0 True False->-> instance Movsxb Reg32 (Disp, Reg32, Reg32, Scale) where->   movsxb (Reg32 dest) (Disp disp, Reg32 5, Reg32 index, s) = x86_widen_memindex dest 5 disp index (scaleToShift s) True False->   movsxb _ _ = onlyEbp->-> instance Movsxb Reg32 (Disp, Reg32, Scale) where->   movsxb (Reg32 dest) (Disp disp, Reg32 index, s) = x86_widen_memindex dest x86_nobasereg disp index (scaleToShift s) True False->-> instance Movsxb Reg32 (Reg32, Reg32, Scale) where->   movsxb (Reg32 dest) (Reg32 base, Reg32 index, s) = x86_widen_memindex dest base 0 index (scaleToShift s) True False--> class Movsxw a b where->   movsxw :: a -> b -> CodeGen e s ()--> instance Movsxw Reg32 Reg16 where->   movsxw (Reg32 dest) (Reg16 source) = x86_widen_reg dest source True True->-> instance Movsxw Reg32 Addr where->   movsxw (Reg32 dest) (Addr source) = x86_widen_mem dest source True True->-> instance Movsxw Reg32 (Disp, Reg32) where->   movsxw (Reg32 dest) (Disp disp, Reg32 source) = x86_widen_membase dest source disp True True->-> instance Movsxw Reg32 Ind where->   movsxw (Reg32 dest) (Ind (Reg32 source)) = x86_widen_membase dest source 0 True True->-> instance Movsxw Reg32 (Disp, Reg32, Reg32, Scale) where->   movsxw (Reg32 dest) (Disp disp, Reg32 5, Reg32 index, s) = x86_widen_memindex dest 5 disp index (scaleToShift s) True True->   movsxw _ _ = onlyEbp->-> instance Movsxw Reg32 (Disp, Reg32, Scale) where->   movsxw (Reg32 dest) (Disp disp, Reg32 index, s) = x86_widen_memindex dest x86_nobasereg disp index (scaleToShift s) True True->-> instance Movsxw Reg32 (Reg32, Reg32, Scale) where->   movsxw (Reg32 dest) (Reg32 base, Reg32 index, s) = x86_widen_memindex dest base 0 index (scaleToShift s) True True---move with zero-extension--> class Movzxb a b where->   movzxb :: a -> b -> CodeGen e s ()--> instance Movzxb Reg32 Reg8 where->   movzxb (Reg32 dest) (Reg8 source) = x86_widen_reg dest source False False->-> instance Movzxb Reg32 Addr where->   movzxb (Reg32 dest) (Addr source) = x86_widen_mem dest source False False->-> instance Movzxb Reg32 (Disp, Reg32) where->   movzxb (Reg32 dest) (Disp disp, Reg32 source) = x86_widen_membase dest source disp False False->-> instance Movzxb Reg32 Ind where->   movzxb (Reg32 dest) (Ind (Reg32 source)) = x86_widen_membase dest source 0 False False->-> instance Movzxb Reg32 (Disp, Reg32, Reg32, Scale) where->   movzxb (Reg32 dest) (Disp disp, Reg32 5, Reg32 index, s) = x86_widen_memindex dest 5 disp index (scaleToShift s) False False->   movzxb _ _ = onlyEbp->-> instance Movzxb Reg32 (Disp, Reg32, Scale) where->   movzxb (Reg32 dest) (Disp disp, Reg32 index, s) = x86_widen_memindex dest x86_nobasereg disp index (scaleToShift s) False False->-> instance Movzxb Reg32 (Reg32, Reg32, Scale) where->   movzxb (Reg32 dest) (Reg32 base, Reg32 index, s) = x86_widen_memindex dest base 0 index (scaleToShift s) False False--> class Movzxw a b where->   movzxw :: a -> b -> CodeGen e s ()--> instance Movzxw Reg32 Reg16 where->   movzxw (Reg32 dest) (Reg16 source) = x86_widen_reg dest source False True->-> instance Movzxw Reg32 Addr where->   movzxw (Reg32 dest) (Addr source) = x86_widen_mem dest source False True->-> instance Movzxw Reg32 (Disp, Reg32) where->   movzxw (Reg32 dest) (Disp disp, Reg32 source) = x86_widen_membase dest source disp False True->-> instance Movzxw Reg32 Ind where->   movzxw (Reg32 dest) (Ind (Reg32 source)) = x86_widen_membase dest source 0 False True->-> instance Movzxw Reg32 (Disp, Reg32, Reg32, Scale) where->   movzxw (Reg32 dest) (Disp disp, Reg32 5, Reg32 index, s) = x86_widen_memindex dest 5 disp index (scaleToShift s) False True->   movzxw _ _ = onlyEbp->-> instance Movzxw Reg32 (Disp, Reg32, Scale) where->   movzxw (Reg32 dest) (Disp disp, Reg32 index, s) = x86_widen_memindex dest x86_nobasereg disp index (scaleToShift s) False True->-> instance Movzxw Reg32 (Reg32, Reg32, Scale) where->   movzxw (Reg32 dest) (Reg32 base, Reg32 index, s) = x86_widen_memindex dest base 0 index (scaleToShift s) False True---load effective address--> class Lea a b where->   lea :: a -> b -> CodeGen e s ()--> instance Lea Reg32 Addr where->   lea (Reg32 dest) (Addr source) = x86_lea_mem dest source ->-> instance Lea Reg32 (Disp, Reg32) where->   lea (Reg32 dest) (Disp disp, Reg32 source) = x86_lea_membase dest source disp ->-> instance Lea Reg32 Ind where->   lea (Reg32 dest) (Ind (Reg32 source)) = x86_lea_membase dest source 0 ->-> instance Lea Reg32 (Disp, Reg32, Reg32, Scale) where->   lea (Reg32 dest) (Disp disp, Reg32 5, Reg32 index, s) = x86_lea_memindex dest 5 disp index (scaleToShift s)->   lea _ _ = onlyEbp->-> instance Lea Reg32 (Disp, Reg32, Scale) where->   lea (Reg32 dest) (Disp disp, Reg32 index, s) = x86_lea_memindex dest x86_nobasereg disp index (scaleToShift s)->-> instance Lea Reg32 (Reg32, Reg32, Scale) where->   lea (Reg32 dest) (Reg32 base, Reg32 index, s) = x86_lea_memindex dest base 0 index (scaleToShift s)---convert word to doubleword--> cdq = x86_cdq---wait for FPU--> wait = x86_wait---push to stack--> class Push a where->   push :: a -> CodeGen e s ()--> instance Push Reg32 where->   push (Reg32 source) = x86_push_reg source ->-> instance Push Ind where->   push (Ind (Reg32 source)) = x86_push_regp source->-> instance Push Addr where->   push (Addr source) = x86_push_mem source ->-> instance Push (Disp, Reg32) where->   push (Disp disp, Reg32 source) = x86_push_membase source disp ->-> instance Push Word32 where->   push imm = x86_push_imm imm ->-> instance Push Label where->   push l = do x86_push_imm_template->               emitFixup l (-4) Fixup32Absolute->-> instance Push (Disp, Reg32, Reg32, Scale) where->   push (Disp disp, Reg32 5, Reg32 index, s) = x86_push_memindex 5 disp index (scaleToShift s)->   push _ = onlyEbp->-> instance Push (Disp, Reg32, Scale) where->   push (Disp disp, Reg32 index, s) = x86_push_memindex x86_nobasereg disp index (scaleToShift s)->-> instance Push (Reg32, Reg32, Scale) where->   push (Reg32 base, Reg32 index, s) = x86_push_memindex base 0 index (scaleToShift s)---pop from stack--> class Pop a where->   pop :: a -> CodeGen e s ()--> instance Pop Reg32 where->   pop (Reg32 dest) = x86_pop_reg dest ->-> instance Pop Addr where->   pop (Addr dest) = x86_pop_mem dest ->-> instance Pop (Disp, Reg32) where->   pop (Disp disp, Reg32 dest) = x86_pop_membase dest disp ->-> instance Pop Ind where->   pop (Ind (Reg32 dest)) = x86_pop_membase dest 0 ---push/pop general purpose registers--> pushad = x86_pushad-> popad  = x86_popad---push/pop EFLAGS--> pushfd = x86_pushfd-> popfd  = x86_popfd---loop according to ECX couter--> loop   :: Word8 -> CodeGen e s ()-> loop   = x86_loop--> loope  :: Word8 -> CodeGen e s ()-> loope  = x86_loope--> loopne :: Word8 -> CodeGen e s ()-> loopne = x86_loopne---jump--> class Jmp a where->   jmp :: a -> CodeGen e s ()--> instance Jmp Word8 where->   jmp imm = x86_jump8 imm ->-> instance Jmp Word32 where->   jmp imm = x86_jump32 imm ->-> instance Jmp Reg32 where->   jmp (Reg32 dest) = x86_jump_reg dest ->-> instance Jmp Addr where->   jmp (Addr dest) = x86_jump_mem dest ->-> instance Jmp (Disp, Reg32) where->   jmp (Disp disp, Reg32 dest) = x86_jump_membase dest disp ->-> instance Jmp Ind where->   jmp (Ind (Reg32 dest)) = x86_jump_membase dest 0 ->-> instance Jmp Label where->   jmp l = do x86_jump32 0->              emitFixup l (-4) Fixup32-              -jump on condition code (branch)--> class Ja a where->   ja :: a -> CodeGen e s ()--> instance Ja Word8 where->   ja imm = x86_branch8 x86_cc_a imm False->-> instance Ja Word32 where->   ja imm = x86_branch32 x86_cc_a imm False--> class Jae a where->   jae :: a -> CodeGen e s ()--> instance Jae Word8 where->   jae imm = x86_branch8 x86_cc_ae imm False->-> instance Jae Word32 where->   jae imm = x86_branch32 x86_cc_ae imm False-> -> instance Jae Label where->   jae l = do x86_branch32 x86_cc_ae 0 False->              emitFixup l (-4) Fixup32--> class Jb a where->   jb :: a -> CodeGen e s ()--> instance Jb Word8 where->   jb imm = x86_branch8 x86_cc_b imm False->-> instance Jb Word32 where->   jb imm = x86_branch32 x86_cc_b imm False-> -> instance Jb Label where->   jb l = do x86_branch32 x86_cc_b 0 False->             emitFixup l (-4) Fixup32--> class Jbe a where->   jbe :: a -> CodeGen e s ()--> instance Jbe Word8 where->   jbe imm = x86_branch8 x86_cc_be imm False->-> instance Jbe Word32 where->   jbe imm = x86_branch32 x86_cc_be imm False-> -> instance Jbe Label where->   jbe l = do x86_branch32 x86_cc_be 0 False->              emitFixup l (-4) Fixup32--> class Jc a where->   jc :: a -> CodeGen e s ()--> instance Jc Word8 where->   jc imm = x86_branch8 x86_cc_c imm False->-> instance Jc Word32 where->   jc imm = x86_branch32 x86_cc_c imm False-> -> instance Jc Label where->   jc l = do x86_branch32 x86_cc_c 0 False->             emitFixup l (-4) Fixup32--> class Je a where->   je :: a -> CodeGen e s ()--> instance Je Word8 where->   je imm = x86_branch8 x86_cc_e imm False->-> instance Je Word32 where->   je imm = x86_branch32 x86_cc_e imm False-> -> instance Je Label where->   je l = do x86_branch32 x86_cc_e 0 False->             emitFixup l (-4) Fixup32--> class Jna a where->   jna :: a -> CodeGen e s ()--> instance Jna Word8 where->   jna imm = x86_branch8 x86_cc_na imm False->-> instance Jna Word32 where->   jna imm = x86_branch32 x86_cc_na imm False-> -> instance Jna Label where->   jna l = do x86_branch32 x86_cc_na 0 False->              emitFixup l (-4) Fixup32--> class Jnae a where->   jnae :: a -> CodeGen e s ()--> instance Jnae Word8 where->   jnae imm = x86_branch8 x86_cc_nae imm False->-> instance Jnae Word32 where->   jnae imm = x86_branch32 x86_cc_nae imm False-> -> instance Jnae Label where->   jnae l = do x86_branch32 x86_cc_nae 0 False->               emitFixup l (-4) Fixup32--> class Jnb a where->   jnb :: a -> CodeGen e s ()--> instance Jnb Word8 where->   jnb imm = x86_branch8 x86_cc_nb imm False->-> instance Jnb Word32 where->   jnb imm = x86_branch32 x86_cc_nb imm False-> -> instance Jnb Label where->   jnb l = do x86_branch32 x86_cc_nb 0 False->              emitFixup l (-4) Fixup32--> class Jnbe a where->   jnbe :: a -> CodeGen e s ()--> instance Jnbe Word8 where->   jnbe imm = x86_branch8 x86_cc_nbe imm False->-> instance Jnbe Word32 where->   jnbe imm = x86_branch32 x86_cc_nbe imm False-> -> instance Jnbe Label where->   jnbe l = do x86_branch32 x86_cc_nbe 0 False->               emitFixup l (-4) Fixup32--> class Jnc a where->   jnc :: a -> CodeGen e s ()--> instance Jnc Word8 where->   jnc imm = x86_branch8 x86_cc_nc imm False->-> instance Jnc Word32 where->   jnc imm = x86_branch32 x86_cc_nc imm False-> -> instance Jnc Label where->   jnc l = do x86_branch32 x86_cc_nc 0 False->              emitFixup l (-4) Fixup32--> class Jne a where->   jne :: a -> CodeGen e s ()--> instance Jne Word8 where->   jne imm = x86_branch8 x86_cc_ne imm False->-> instance Jne Word32 where->   jne imm = x86_branch32 x86_cc_ne imm False-> -> instance Jne Label where->   jne l = do x86_branch32 x86_cc_ne 0 False->              emitFixup l (-4) Fixup32--> class Jnp a where->   jnp :: a -> CodeGen e s ()--> instance Jnp Word8 where->   jnp imm = x86_branch8 x86_cc_np imm False->-> instance Jnp Word32 where->   jnp imm = x86_branch32 x86_cc_np imm False-> -> instance Jnp Label where->   jnp l = do x86_branch32 x86_cc_np 0 False->              emitFixup l (-4) Fixup32--> class Jnz a where->   jnz :: a -> CodeGen e s ()--> instance Jnz Word8 where->   jnz imm = x86_branch8 x86_cc_nz imm False->-> instance Jnz Word32 where->   jnz imm = x86_branch32 x86_cc_nz imm False-> -> instance Jnz Label where->   jnz l = do x86_branch32 x86_cc_nz 0 False->              emitFixup l (-4) Fixup32--> class Jp a where->   jp :: a -> CodeGen e s ()--> instance Jp Word8 where->   jp imm = x86_branch8 x86_cc_p imm False->-> instance Jp Word32 where->   jp imm = x86_branch32 x86_cc_p imm False-> -> instance Jp Label where->   jp l = do x86_branch32 x86_cc_p 0 False->             emitFixup l (-4) Fixup32--> class Jpe a where->   jpe :: a -> CodeGen e s ()--> instance Jpe Word8 where->   jpe imm = x86_branch8 x86_cc_pe imm False->-> instance Jpe Word32 where->   jpe imm = x86_branch32 x86_cc_pe imm False-> -> instance Jpe Label where->   jpe l = do x86_branch32 x86_cc_pe 0 False->              emitFixup l (-4) Fixup32--> class Jpo a where->   jpo :: a -> CodeGen e s ()--> instance Jpo Word8 where->   jpo imm = x86_branch8 x86_cc_po imm False->-> instance Jpo Word32 where->   jpo imm = x86_branch32 x86_cc_po imm False-> -> instance Jpo Label where->   jpo l = do x86_branch32 x86_cc_po 0 False->              emitFixup l (-4) Fixup32--> class Jz a where->   jz :: a -> CodeGen e s ()--> instance Jz Word8 where->   jz imm = x86_branch8 x86_cc_z imm False->-> instance Jz Word32 where->   jz imm = x86_branch32 x86_cc_z imm False-> -> instance Jz Label where->   jz l = do x86_branch32 x86_cc_z 0 False->             emitFixup l (-4) Fixup32--> class Jg a where->   jg :: a -> CodeGen e s ()--> instance Jg Word8 where->   jg imm = x86_branch8 x86_cc_gt imm True->-> instance Jg Word32 where->   jg imm = x86_branch32 x86_cc_gt imm True-> -> instance Jg Label where->   jg l = do x86_branch32 x86_cc_gt 0 True->             emitFixup l (-4) Fixup32--> class Jge a where->   jge :: a -> CodeGen e s ()--> instance Jge Word8 where->   jge imm = x86_branch8 x86_cc_ge imm True->-> instance Jge Word32 where->   jge imm = x86_branch32 x86_cc_ge imm True-> -> instance Jge Label where->   jge l = do x86_branch32 x86_cc_ge 0 True->              emitFixup l (-4) Fixup32--> class Jl a where->   jl :: a -> CodeGen e s ()--> instance Jl Word8 where->   jl imm = x86_branch8 x86_cc_lt imm True->-> instance Jl Word32 where->   jl imm = x86_branch32 x86_cc_lt imm True-> -> instance Jl Label where->   jl l = do x86_branch32 x86_cc_lt 0 True->             emitFixup l (-4) Fixup32--> class Jle a where->   jle :: a -> CodeGen e s ()--> instance Jle Word8 where->   jle imm = x86_branch8 x86_cc_le imm True->-> instance Jle Word32 where->   jle imm = x86_branch32 x86_cc_le imm True-> -> instance Jle Label where->   jle l = do x86_branch32 x86_cc_le 0 True->              emitFixup l (-4) Fixup32--> class Jng a where->   jng :: a -> CodeGen e s ()--> instance Jng Word8 where->   jng imm = x86_branch8 x86_cc_le imm True->-> instance Jng Word32 where->   jng imm = x86_branch32 x86_cc_le imm True-> -> instance Jng Label where->   jng l = do x86_branch32 x86_cc_le 0 True->              emitFixup l (-4) Fixup32--> class Jnge a where->   jnge :: a -> CodeGen e s ()--> instance Jnge Word8 where->   jnge imm = x86_branch8 x86_cc_lt imm True->-> instance Jnge Word32 where->   jnge imm = x86_branch32 x86_cc_lt imm True-> -> instance Jnge Label where->   jnge l = do x86_branch32 x86_cc_lt 0 True->               emitFixup l (-4) Fixup32--> class Jnl a where->   jnl :: a -> CodeGen e s ()--> instance Jnl Word8 where->   jnl imm = x86_branch8 x86_cc_ge imm True->-> instance Jnl Word32 where->   jnl imm = x86_branch32 x86_cc_ge imm True-> -> instance Jnl Label where->   jnl l = do x86_branch32 x86_cc_ge 0 True->              emitFixup l (-4) Fixup32--> class Jnle a where->   jnle :: a -> CodeGen e s ()--> instance Jnle Word8 where->   jnle imm = x86_branch8 x86_cc_gt imm True->-> instance Jnle Word32 where->   jnle imm = x86_branch32 x86_cc_gt imm True-> -> instance Jnle Label where->   jnle l = do x86_branch32 x86_cc_gt 0 True->               emitFixup l (-4) Fixup32--> class Jno a where->   jno :: a -> CodeGen e s ()--> instance Jno Word8 where->   jno imm = x86_branch8 x86_cc_no imm True->-> instance Jno Word32 where->   jno imm = x86_branch32 x86_cc_no imm True-> -> instance Jno Label where->   jno l = do x86_branch32 x86_cc_no 0 True->              emitFixup l (-4) Fixup32--> class Jns a where->   jns :: a -> CodeGen e s ()--> instance Jns Word8 where->   jns imm = x86_branch8 x86_cc_ns imm True->-> instance Jns Word32 where->   jns imm = x86_branch32 x86_cc_ns imm True-> -> instance Jns Label where->   jns l = do x86_branch32 x86_cc_ns 0 True->              emitFixup l (-4) Fixup32--> class Jo a where->   jo :: a -> CodeGen e s ()--> instance Jo Word8 where->   jo imm = x86_branch8 x86_cc_o imm True->-> instance Jo Word32 where->   jo imm = x86_branch32 x86_cc_o imm True-> -> instance Jo Label where->   jo l = do x86_branch32 x86_cc_o 0 True->             emitFixup l (-4) Fixup32--> class Js a where->   js :: a -> CodeGen e s ()--> instance Js Word8 where->   js imm = x86_branch8 x86_cc_s imm True->-> instance Js Word32 where->   js imm = x86_branch32 x86_cc_s imm True-> -> instance Js Label where->   js l = do x86_branch32 x86_cc_s 0 True->             emitFixup l (-4) Fixup32--jump if ecx register is 0--> jecxz :: Word8 -> CodeGen e s ()-> jecxz = x86_jecxz---set byte on condition code--> class Seta a where->   seta :: a -> CodeGen e s ()--> instance Seta Reg8 where->   seta (Reg8 dest) = x86_set_reg x86_cc_a dest False->-> instance Seta Addr where->   seta (Addr dest) = x86_set_mem x86_cc_a dest False->-> instance Seta (Disp, Reg32) where->   seta (Disp disp, Reg32 dest) = x86_set_membase x86_cc_a dest disp False->-> instance Seta Ind where->   seta (Ind (Reg32 dest)) = x86_set_membase x86_cc_a dest 0 False--> class Setae a where->   setae :: a -> CodeGen e s ()--> instance Setae Reg8 where->   setae (Reg8 dest) = x86_set_reg x86_cc_ae dest False->-> instance Setae Addr where->   setae (Addr dest) = x86_set_mem x86_cc_ae dest False->-> instance Setae (Disp, Reg32) where->   setae (Disp disp, Reg32 dest) = x86_set_membase x86_cc_ae dest disp False->-> instance Setae Ind where->   setae (Ind (Reg32 dest)) = x86_set_membase x86_cc_ae dest 0 False--> class Setb a where->   setb :: a -> CodeGen e s ()--> instance Setb Reg8 where->   setb (Reg8 dest) = x86_set_reg x86_cc_b dest False->-> instance Setb Addr where->   setb (Addr dest) = x86_set_mem x86_cc_b dest False->-> instance Setb (Disp, Reg32) where->   setb (Disp disp, Reg32 dest) = x86_set_membase x86_cc_b dest disp False->-> instance Setb Ind where->   setb (Ind (Reg32 dest)) = x86_set_membase x86_cc_b dest 0 False--> class Setbe a where->   setbe :: a -> CodeGen e s ()--> instance Setbe Reg8 where->   setbe (Reg8 dest) = x86_set_reg x86_cc_be dest False->-> instance Setbe Addr where->   setbe (Addr dest) = x86_set_mem x86_cc_be dest False->-> instance Setbe (Disp, Reg32) where->   setbe (Disp disp, Reg32 dest) = x86_set_membase x86_cc_be dest disp False->-> instance Setbe Ind where->   setbe (Ind (Reg32 dest)) = x86_set_membase x86_cc_be dest 0 False--> class Setc a where->   setc :: a -> CodeGen e s ()--> instance Setc Reg8 where->   setc (Reg8 dest) = x86_set_reg x86_cc_c dest False->-> instance Setc Addr where->   setc (Addr dest) = x86_set_mem x86_cc_c dest False->-> instance Setc (Disp, Reg32) where->   setc (Disp disp, Reg32 dest) = x86_set_membase x86_cc_c dest disp False->-> instance Setc Ind where->   setc (Ind (Reg32 dest)) = x86_set_membase x86_cc_c dest 0 False--> class Sete a where->   sete :: a -> CodeGen e s ()--> instance Sete Reg8 where->   sete (Reg8 dest) = x86_set_reg x86_cc_e dest False->-> instance Sete Addr where->   sete (Addr dest) = x86_set_mem x86_cc_e dest False->-> instance Sete (Disp, Reg32) where->   sete (Disp disp, Reg32 dest) = x86_set_membase x86_cc_e dest disp False->-> instance Sete Ind where->   sete (Ind (Reg32 dest)) = x86_set_membase x86_cc_e dest 0 False--> class Setna a where->   setna :: a -> CodeGen e s ()--> instance Setna Reg8 where->   setna (Reg8 dest) = x86_set_reg x86_cc_na dest False->-> instance Setna Addr where->   setna (Addr dest) = x86_set_mem x86_cc_na dest False->-> instance Setna (Disp, Reg32) where->   setna (Disp disp, Reg32 dest) = x86_set_membase x86_cc_na dest disp False->-> instance Setna Ind where->   setna (Ind (Reg32 dest)) = x86_set_membase x86_cc_na dest 0 False--> class Setnae a where->   setnae :: a -> CodeGen e s ()--> instance Setnae Reg8 where->   setnae (Reg8 dest) = x86_set_reg x86_cc_nae dest False->-> instance Setnae Addr where->   setnae (Addr dest) = x86_set_mem x86_cc_nae dest False->-> instance Setnae (Disp, Reg32) where->   setnae (Disp disp, Reg32 dest) = x86_set_membase x86_cc_nae dest disp False->-> instance Setnae Ind where->   setnae (Ind (Reg32 dest)) = x86_set_membase x86_cc_nae dest 0 False--> class Setnb a where->   setnb :: a -> CodeGen e s ()--> instance Setnb Reg8 where->   setnb (Reg8 dest) = x86_set_reg x86_cc_nb dest False->-> instance Setnb Addr where->   setnb (Addr dest) = x86_set_mem x86_cc_nb dest False->-> instance Setnb (Disp, Reg32) where->   setnb (Disp disp, Reg32 dest) = x86_set_membase x86_cc_nb dest disp False->-> instance Setnb Ind where->   setnb (Ind (Reg32 dest)) = x86_set_membase x86_cc_nb dest 0 False--> class Setnbe a where->   setnbe :: a -> CodeGen e s ()--> instance Setnbe Reg8 where->   setnbe (Reg8 dest) = x86_set_reg x86_cc_nbe dest False->-> instance Setnbe Addr where->   setnbe (Addr dest) = x86_set_mem x86_cc_nbe dest False->-> instance Setnbe (Disp, Reg32) where->   setnbe (Disp disp, Reg32 dest) = x86_set_membase x86_cc_nbe dest disp False->-> instance Setnbe Ind where->   setnbe (Ind (Reg32 dest)) = x86_set_membase x86_cc_nbe dest 0 False--> class Setnc a where->   setnc :: a -> CodeGen e s ()--> instance Setnc Reg8 where->   setnc (Reg8 dest) = x86_set_reg x86_cc_nc dest False->-> instance Setnc Addr where->   setnc (Addr dest) = x86_set_mem x86_cc_nc dest False->-> instance Setnc (Disp, Reg32) where->   setnc (Disp disp, Reg32 dest) = x86_set_membase x86_cc_nc dest disp False->-> instance Setnc Ind where->   setnc (Ind (Reg32 dest)) = x86_set_membase x86_cc_nc dest 0 False--> class Setne a where->   setne :: a -> CodeGen e s ()--> instance Setne Reg8 where->   setne (Reg8 dest) = x86_set_reg x86_cc_ne dest False->-> instance Setne Addr where->   setne (Addr dest) = x86_set_mem x86_cc_ne dest False->-> instance Setne (Disp, Reg32) where->   setne (Disp disp, Reg32 dest) = x86_set_membase x86_cc_ne dest disp False->-> instance Setne Ind where->   setne (Ind (Reg32 dest)) = x86_set_membase x86_cc_ne dest 0 False--> class Setnp a where->   setnp :: a -> CodeGen e s ()--> instance Setnp Reg8 where->   setnp (Reg8 dest) = x86_set_reg x86_cc_np dest False->-> instance Setnp Addr where->   setnp (Addr dest) = x86_set_mem x86_cc_np dest False->-> instance Setnp (Disp, Reg32) where->   setnp (Disp disp, Reg32 dest) = x86_set_membase x86_cc_np dest disp False->-> instance Setnp Ind where->   setnp (Ind (Reg32 dest)) = x86_set_membase x86_cc_np dest 0 False--> class Setnz a where->   setnz :: a -> CodeGen e s ()--> instance Setnz Reg8 where->   setnz (Reg8 dest) = x86_set_reg x86_cc_nz dest False->-> instance Setnz Addr where->   setnz (Addr dest) = x86_set_mem x86_cc_nz dest False->-> instance Setnz (Disp, Reg32) where->   setnz (Disp disp, Reg32 dest) = x86_set_membase x86_cc_nz dest disp False->-> instance Setnz Ind where->   setnz (Ind (Reg32 dest)) = x86_set_membase x86_cc_nz dest 0 False--> class Setp a where->   setp :: a -> CodeGen e s ()--> instance Setp Reg8 where->   setp (Reg8 dest) = x86_set_reg x86_cc_p dest False->-> instance Setp Addr where->   setp (Addr dest) = x86_set_mem x86_cc_p dest False->-> instance Setp (Disp, Reg32) where->   setp (Disp disp, Reg32 dest) = x86_set_membase x86_cc_p dest disp False->-> instance Setp Ind where->   setp (Ind (Reg32 dest)) = x86_set_membase x86_cc_p dest 0 False--> class Setpe a where->   setpe :: a -> CodeGen e s ()--> instance Setpe Reg8 where->   setpe (Reg8 dest) = x86_set_reg x86_cc_pe dest False->-> instance Setpe Addr where->   setpe (Addr dest) = x86_set_mem x86_cc_pe dest False->-> instance Setpe (Disp, Reg32) where->   setpe (Disp disp, Reg32 dest) = x86_set_membase x86_cc_pe dest disp False->-> instance Setpe Ind where->   setpe (Ind (Reg32 dest)) = x86_set_membase x86_cc_pe dest 0 False--> class Setpo a where->   setpo :: a -> CodeGen e s ()--> instance Setpo Reg8 where->   setpo (Reg8 dest) = x86_set_reg x86_cc_po dest False->-> instance Setpo Addr where->   setpo (Addr dest) = x86_set_mem x86_cc_po dest False->-> instance Setpo (Disp, Reg32) where->   setpo (Disp disp, Reg32 dest) = x86_set_membase x86_cc_po dest disp False->-> instance Setpo Ind where->   setpo (Ind (Reg32 dest)) = x86_set_membase x86_cc_po dest 0 False--> class Setg a where->   setg :: a -> CodeGen e s ()--> instance Setg Reg8 where->   setg (Reg8 dest) = x86_set_reg x86_cc_gt dest True->-> instance Setg Addr where->   setg (Addr dest) = x86_set_mem x86_cc_gt dest True->-> instance Setg (Disp, Reg32) where->   setg (Disp disp, Reg32 dest) = x86_set_membase x86_cc_gt dest disp True->-> instance Setg Ind where->   setg (Ind (Reg32 dest)) = x86_set_membase x86_cc_gt dest 0 True--> class Setge a where->   setge :: a -> CodeGen e s ()--> instance Setge Reg8 where->   setge (Reg8 dest) = x86_set_reg x86_cc_ge dest True->-> instance Setge Addr where->   setge (Addr dest) = x86_set_mem x86_cc_ge dest True->-> instance Setge (Disp, Reg32) where->   setge (Disp disp, Reg32 dest) = x86_set_membase x86_cc_ge dest disp True->-> instance Setge Ind where->   setge (Ind (Reg32 dest)) = x86_set_membase x86_cc_ge dest 0 True--> class Setl a where->   setl :: a -> CodeGen e s ()--> instance Setl Reg8 where->   setl (Reg8 dest) = x86_set_reg x86_cc_lt dest True->-> instance Setl Addr where->   setl (Addr dest) = x86_set_mem x86_cc_lt dest True->-> instance Setl (Disp, Reg32) where->   setl (Disp disp, Reg32 dest) = x86_set_membase x86_cc_lt dest disp True->-> instance Setl Ind where->   setl (Ind (Reg32 dest)) = x86_set_membase x86_cc_lt dest 0 True--> class Setle a where->   setle :: a -> CodeGen e s ()--> instance Setle Reg8 where->   setle (Reg8 dest) = x86_set_reg x86_cc_le dest True->-> instance Setle Addr where->   setle (Addr dest) = x86_set_mem x86_cc_le dest True->-> instance Setle (Disp, Reg32) where->   setle (Disp disp, Reg32 dest) = x86_set_membase x86_cc_le dest disp True->-> instance Setle Ind where->   setle (Ind (Reg32 dest)) = x86_set_membase x86_cc_le dest 0 True--> class Setng a where->   setng :: a -> CodeGen e s ()--> instance Setng Reg8 where->   setng (Reg8 dest) = x86_set_reg x86_cc_le dest True->-> instance Setng Addr where->   setng (Addr dest) = x86_set_mem x86_cc_le dest True->-> instance Setng (Disp, Reg32) where->   setng (Disp disp, Reg32 dest) = x86_set_membase x86_cc_le dest disp True->-> instance Setng Ind where->   setng (Ind (Reg32 dest)) = x86_set_membase x86_cc_le dest 0 True--> class Setnge a where->   setnge :: a -> CodeGen e s ()--> instance Setnge Reg8 where->   setnge (Reg8 dest) = x86_set_reg x86_cc_lt dest True->-> instance Setnge Addr where->   setnge (Addr dest) = x86_set_mem x86_cc_lt dest True->-> instance Setnge (Disp, Reg32) where->   setnge (Disp disp, Reg32 dest) = x86_set_membase x86_cc_lt dest disp True->-> instance Setnge Ind where->   setnge (Ind (Reg32 dest)) = x86_set_membase x86_cc_lt dest 0 True--> class Setnl a where->   setnl :: a -> CodeGen e s ()--> instance Setnl Reg8 where->   setnl (Reg8 dest) = x86_set_reg x86_cc_ge dest True->-> instance Setnl Addr where->   setnl (Addr dest) = x86_set_mem x86_cc_ge dest True->-> instance Setnl (Disp, Reg32) where->   setnl (Disp disp, Reg32 dest) = x86_set_membase x86_cc_ge dest disp True->-> instance Setnl Ind where->   setnl (Ind (Reg32 dest)) = x86_set_membase x86_cc_ge dest 0 True--> class Setnle a where->   setnle :: a -> CodeGen e s ()--> instance Setnle Reg8 where->   setnle (Reg8 dest) = x86_set_reg x86_cc_gt dest True->-> instance Setnle Addr where->   setnle (Addr dest) = x86_set_mem x86_cc_gt dest True->-> instance Setnle (Disp, Reg32) where->   setnle (Disp disp, Reg32 dest) = x86_set_membase x86_cc_gt dest disp True->-> instance Setnle Ind where->   setnle (Ind (Reg32 dest)) = x86_set_membase x86_cc_gt dest 0 True--> class Setno a where->   setno :: a -> CodeGen e s ()--> instance Setno Reg8 where->   setno (Reg8 dest) = x86_set_reg x86_cc_no dest True->-> instance Setno Addr where->   setno (Addr dest) = x86_set_mem x86_cc_no dest True->-> instance Setno (Disp, Reg32) where->   setno (Disp disp, Reg32 dest) = x86_set_membase x86_cc_no dest disp True->-> instance Setno Ind where->   setno (Ind (Reg32 dest)) = x86_set_membase x86_cc_no dest 0 True--> class Setns a where->   setns :: a -> CodeGen e s ()--> instance Setns Reg8 where->   setns (Reg8 dest) = x86_set_reg x86_cc_ns dest True->-> instance Setns Addr where->   setns (Addr dest) = x86_set_mem x86_cc_ns dest True->-> instance Setns (Disp, Reg32) where->   setns (Disp disp, Reg32 dest) = x86_set_membase x86_cc_ns dest disp True->-> instance Setns Ind where->   setns (Ind (Reg32 dest)) = x86_set_membase x86_cc_ns dest 0 True--> class Seto a where->   seto :: a -> CodeGen e s ()--> instance Seto Reg8 where->   seto (Reg8 dest) = x86_set_reg x86_cc_o dest True->-> instance Seto Addr where->   seto (Addr dest) = x86_set_mem x86_cc_o dest True->-> instance Seto (Disp, Reg32) where->   seto (Disp disp, Reg32 dest) = x86_set_membase x86_cc_o dest disp True->-> instance Seto Ind where->   seto (Ind (Reg32 dest)) = x86_set_membase x86_cc_o dest 0 True--> class Sets a where->   sets :: a -> CodeGen e s ()--> instance Sets Reg8 where->   sets (Reg8 dest) = x86_set_reg x86_cc_s dest True->-> instance Sets Addr where->   sets (Addr dest) = x86_set_mem x86_cc_s dest True->-> instance Sets (Disp, Reg32) where->   sets (Disp disp, Reg32 dest) = x86_set_membase x86_cc_s dest disp True->-> instance Sets Ind where->   sets (Ind (Reg32 dest)) = x86_set_membase x86_cc_s dest 0 True--> class Setz a where->   setz :: a -> CodeGen e s ()--> instance Setz Reg8 where->   setz (Reg8 dest) = x86_set_reg x86_cc_z dest False->-> instance Setz Addr where->   setz (Addr dest) = x86_set_mem x86_cc_z dest False->-> instance Setz (Disp, Reg32) where->   setz (Disp disp, Reg32 dest) = x86_set_membase x86_cc_z dest disp False->-> instance Setz Ind where->   setz (Ind (Reg32 dest)) = x86_set_membase x86_cc_z dest 0 False---call procedure--> class Call a where->   call :: a -> CodeGen e s ()--> instance Call Word32 where->   call imm = x86_call_imm imm ->-> instance Call Label where->   call l = do x86_call_imm 0->               emitFixup l (-4) Fixup32->-> instance Call Reg32 where->   call (Reg32 dest) = x86_call_reg dest ->-> instance Call Addr where->   call (Addr dest) = x86_call_mem dest ->-> instance Call (Disp, Reg32) where->   call (Disp disp, Reg32 dest) = x86_call_membase dest disp ->-> instance Call Ind where->   call (Ind (Reg32 dest)) = x86_call_membase dest 0 ->-> instance Call (FunPtr a) where->   call = x86_call_hs---return from procedure--> ret :: CodeGen e s ()-> ret = x86_ret->-> retN :: Word16 -> CodeGen e s ()-> retN n = x86_ret_imm n---make stack frame--> enter :: Word16 -> CodeGen e s ()-> enter = x86_enter---conditional move--> class Cmova a b where->   cmova :: a -> b -> CodeGen e s ()--> instance Cmova Reg32 Reg32 where->   cmova (Reg32 dest) (Reg32 source) = x86_cmov_reg x86_cc_a False dest source->-> instance Cmova Reg32 Addr where->   cmova (Reg32 dest) (Addr source) = x86_cmov_mem x86_cc_a False dest source->-> instance Cmova Reg32 (Disp, Reg32) where->   cmova (Reg32 dest) (Disp disp, Reg32 source) = x86_cmov_membase x86_cc_a False dest source disp->-> instance Cmova Reg32 Ind where->   cmova (Reg32 dest) (Ind (Reg32 source)) = x86_cmov_membase x86_cc_a False dest source 0--> class Cmovae a b where->   cmovae :: a -> b -> CodeGen e s ()--> instance Cmovae Reg32 Reg32 where->   cmovae (Reg32 dest) (Reg32 source) = x86_cmov_reg x86_cc_ae False dest source->-> instance Cmovae Reg32 Addr where->   cmovae (Reg32 dest) (Addr source) = x86_cmov_mem x86_cc_ae False dest source->-> instance Cmovae Reg32 (Disp, Reg32) where->   cmovae (Reg32 dest) (Disp disp, Reg32 source) = x86_cmov_membase x86_cc_ae False dest source disp->-> instance Cmovae Reg32 Ind where->   cmovae (Reg32 dest) (Ind (Reg32 source)) = x86_cmov_membase x86_cc_ae False dest source 0--> class Cmovb a b where->   cmovb :: a -> b -> CodeGen e s ()--> instance Cmovb Reg32 Reg32 where->   cmovb (Reg32 dest) (Reg32 source) = x86_cmov_reg x86_cc_b False dest source->-> instance Cmovb Reg32 Addr where->   cmovb (Reg32 dest) (Addr source) = x86_cmov_mem x86_cc_b False dest source->-> instance Cmovb Reg32 (Disp, Reg32) where->   cmovb (Reg32 dest) (Disp disp, Reg32 source) = x86_cmov_membase x86_cc_b False dest source disp->-> instance Cmovb Reg32 Ind where->   cmovb (Reg32 dest) (Ind (Reg32 source)) = x86_cmov_membase x86_cc_b False dest source 0--> class Cmovbe a b where->   cmovbe :: a -> b -> CodeGen e s ()--> instance Cmovbe Reg32 Reg32 where->   cmovbe (Reg32 dest) (Reg32 source) = x86_cmov_reg x86_cc_be False dest source->-> instance Cmovbe Reg32 Addr where->   cmovbe (Reg32 dest) (Addr source) = x86_cmov_mem x86_cc_be False dest source->-> instance Cmovbe Reg32 (Disp, Reg32) where->   cmovbe (Reg32 dest) (Disp disp, Reg32 source) = x86_cmov_membase x86_cc_be False dest source disp->-> instance Cmovbe Reg32 Ind where->   cmovbe (Reg32 dest) (Ind (Reg32 source)) = x86_cmov_membase x86_cc_be False dest source 0--> class Cmovc a b where->   cmovc :: a -> b -> CodeGen e s ()--> instance Cmovc Reg32 Reg32 where->   cmovc (Reg32 dest) (Reg32 source) = x86_cmov_reg x86_cc_c False dest source->-> instance Cmovc Reg32 Addr where->   cmovc (Reg32 dest) (Addr source) = x86_cmov_mem x86_cc_c False dest source->-> instance Cmovc Reg32 (Disp, Reg32) where->   cmovc (Reg32 dest) (Disp disp, Reg32 source) = x86_cmov_membase x86_cc_c False dest source disp->-> instance Cmovc Reg32 Ind where->   cmovc (Reg32 dest) (Ind (Reg32 source)) = x86_cmov_membase x86_cc_c False dest source 0--> class Cmove a b where->   cmove :: a -> b -> CodeGen e s ()--> instance Cmove Reg32 Reg32 where->   cmove (Reg32 dest) (Reg32 source) = x86_cmov_reg x86_cc_e False dest source->-> instance Cmove Reg32 Addr where->   cmove (Reg32 dest) (Addr source) = x86_cmov_mem x86_cc_e False dest source->-> instance Cmove Reg32 (Disp, Reg32) where->   cmove (Reg32 dest) (Disp disp, Reg32 source) = x86_cmov_membase x86_cc_e False dest source disp->-> instance Cmove Reg32 Ind where->   cmove (Reg32 dest) (Ind (Reg32 source)) = x86_cmov_membase x86_cc_e False dest source 0--> class Cmovna a b where->   cmovna :: a -> b -> CodeGen e s ()--> instance Cmovna Reg32 Reg32 where->   cmovna (Reg32 dest) (Reg32 source) = x86_cmov_reg x86_cc_na False dest source->-> instance Cmovna Reg32 Addr where->   cmovna (Reg32 dest) (Addr source) = x86_cmov_mem x86_cc_na False dest source->-> instance Cmovna Reg32 (Disp, Reg32) where->   cmovna (Reg32 dest) (Disp disp, Reg32 source) = x86_cmov_membase x86_cc_na False dest source disp->-> instance Cmovna Reg32 Ind where->   cmovna (Reg32 dest) (Ind (Reg32 source)) = x86_cmov_membase x86_cc_na False dest source 0--> class Cmovnae a b where->   cmovnae :: a -> b -> CodeGen e s ()--> instance Cmovnae Reg32 Reg32 where->   cmovnae (Reg32 dest) (Reg32 source) = x86_cmov_reg x86_cc_nae False dest source->-> instance Cmovnae Reg32 Addr where->   cmovnae (Reg32 dest) (Addr source) = x86_cmov_mem x86_cc_nae False dest source->-> instance Cmovnae Reg32 (Disp, Reg32) where->   cmovnae (Reg32 dest) (Disp disp, Reg32 source) = x86_cmov_membase x86_cc_nae False dest source disp->-> instance Cmovnae Reg32 Ind where->   cmovnae (Reg32 dest) (Ind (Reg32 source)) = x86_cmov_membase x86_cc_nae False dest source 0--> class Cmovnb a b where->   cmovnb :: a -> b -> CodeGen e s ()--> instance Cmovnb Reg32 Reg32 where->   cmovnb (Reg32 dest) (Reg32 source) = x86_cmov_reg x86_cc_nb False dest source->-> instance Cmovnb Reg32 Addr where->   cmovnb (Reg32 dest) (Addr source) = x86_cmov_mem x86_cc_nb False dest source->-> instance Cmovnb Reg32 (Disp, Reg32) where->   cmovnb (Reg32 dest) (Disp disp, Reg32 source) = x86_cmov_membase x86_cc_nb False dest source disp->-> instance Cmovnb Reg32 Ind where->   cmovnb (Reg32 dest) (Ind (Reg32 source)) = x86_cmov_membase x86_cc_nb False dest source 0--> class Cmovnbe a b where->   cmovnbe :: a -> b -> CodeGen e s ()--> instance Cmovnbe Reg32 Reg32 where->   cmovnbe (Reg32 dest) (Reg32 source) = x86_cmov_reg x86_cc_nbe False dest source->-> instance Cmovnbe Reg32 Addr where->   cmovnbe (Reg32 dest) (Addr source) = x86_cmov_mem x86_cc_nbe False dest source->-> instance Cmovnbe Reg32 (Disp, Reg32) where->   cmovnbe (Reg32 dest) (Disp disp, Reg32 source) = x86_cmov_membase x86_cc_nbe False dest source disp->-> instance Cmovnbe Reg32 Ind where->   cmovnbe (Reg32 dest) (Ind (Reg32 source)) = x86_cmov_membase x86_cc_nbe False dest source 0--> class Cmovnc a b where->   cmovnc :: a -> b -> CodeGen e s ()--> instance Cmovnc Reg32 Reg32 where->   cmovnc (Reg32 dest) (Reg32 source) = x86_cmov_reg x86_cc_nc False dest source->-> instance Cmovnc Reg32 Addr where->   cmovnc (Reg32 dest) (Addr source) = x86_cmov_mem x86_cc_nc False dest source->-> instance Cmovnc Reg32 (Disp, Reg32) where->   cmovnc (Reg32 dest) (Disp disp, Reg32 source) = x86_cmov_membase x86_cc_nc False dest source disp->-> instance Cmovnc Reg32 Ind where->   cmovnc (Reg32 dest) (Ind (Reg32 source)) = x86_cmov_membase x86_cc_nc False dest source 0--> class Cmovne a b where->   cmovne :: a -> b -> CodeGen e s ()--> instance Cmovne Reg32 Reg32 where->   cmovne (Reg32 dest) (Reg32 source) = x86_cmov_reg x86_cc_ne False dest source->-> instance Cmovne Reg32 Addr where->   cmovne (Reg32 dest) (Addr source) = x86_cmov_mem x86_cc_ne False dest source->-> instance Cmovne Reg32 (Disp, Reg32) where->   cmovne (Reg32 dest) (Disp disp, Reg32 source) = x86_cmov_membase x86_cc_ne False dest source disp->-> instance Cmovne Reg32 Ind where->   cmovne (Reg32 dest) (Ind (Reg32 source)) = x86_cmov_membase x86_cc_ne False dest source 0--> class Cmovnp a b where->   cmovnp :: a -> b -> CodeGen e s ()--> instance Cmovnp Reg32 Reg32 where->   cmovnp (Reg32 dest) (Reg32 source) = x86_cmov_reg x86_cc_np False dest source->-> instance Cmovnp Reg32 Addr where->   cmovnp (Reg32 dest) (Addr source) = x86_cmov_mem x86_cc_np False dest source->-> instance Cmovnp Reg32 (Disp, Reg32) where->   cmovnp (Reg32 dest) (Disp disp, Reg32 source) = x86_cmov_membase x86_cc_np False dest source disp->-> instance Cmovnp Reg32 Ind where->   cmovnp (Reg32 dest) (Ind (Reg32 source)) = x86_cmov_membase x86_cc_np False dest source 0--> class Cmovnz a b where->   cmovnz :: a -> b -> CodeGen e s ()--> instance Cmovnz Reg32 Reg32 where->   cmovnz (Reg32 dest) (Reg32 source) = x86_cmov_reg x86_cc_nz False dest source->-> instance Cmovnz Reg32 Addr where->   cmovnz (Reg32 dest) (Addr source) = x86_cmov_mem x86_cc_nz False dest source->-> instance Cmovnz Reg32 (Disp, Reg32) where->   cmovnz (Reg32 dest) (Disp disp, Reg32 source) = x86_cmov_membase x86_cc_nz False dest source disp->-> instance Cmovnz Reg32 Ind where->   cmovnz (Reg32 dest) (Ind (Reg32 source)) = x86_cmov_membase x86_cc_nz False dest source 0--> class Cmovp a b where->   cmovp :: a -> b -> CodeGen e s ()--> instance Cmovp Reg32 Reg32 where->   cmovp (Reg32 dest) (Reg32 source) = x86_cmov_reg x86_cc_p False dest source->-> instance Cmovp Reg32 Addr where->   cmovp (Reg32 dest) (Addr source) = x86_cmov_mem x86_cc_p False dest source->-> instance Cmovp Reg32 (Disp, Reg32) where->   cmovp (Reg32 dest) (Disp disp, Reg32 source) = x86_cmov_membase x86_cc_p False dest source disp->-> instance Cmovp Reg32 Ind where->   cmovp (Reg32 dest) (Ind (Reg32 source)) = x86_cmov_membase x86_cc_p False dest source 0--> class Cmovpe a b where->   cmovpe :: a -> b -> CodeGen e s ()--> instance Cmovpe Reg32 Reg32 where->   cmovpe (Reg32 dest) (Reg32 source) = x86_cmov_reg x86_cc_pe False dest source->-> instance Cmovpe Reg32 Addr where->   cmovpe (Reg32 dest) (Addr source) = x86_cmov_mem x86_cc_pe False dest source->-> instance Cmovpe Reg32 (Disp, Reg32) where->   cmovpe (Reg32 dest) (Disp disp, Reg32 source) = x86_cmov_membase x86_cc_pe False dest source disp->-> instance Cmovpe Reg32 Ind where->   cmovpe (Reg32 dest) (Ind (Reg32 source)) = x86_cmov_membase x86_cc_pe False dest source 0--> class Cmovpo a b where->   cmovpo :: a -> b -> CodeGen e s ()--> instance Cmovpo Reg32 Reg32 where->   cmovpo (Reg32 dest) (Reg32 source) = x86_cmov_reg x86_cc_po False dest source->-> instance Cmovpo Reg32 Addr where->   cmovpo (Reg32 dest) (Addr source) = x86_cmov_mem x86_cc_po False dest source->-> instance Cmovpo Reg32 (Disp, Reg32) where->   cmovpo (Reg32 dest) (Disp disp, Reg32 source) = x86_cmov_membase x86_cc_po False dest source disp->-> instance Cmovpo Reg32 Ind where->   cmovpo (Reg32 dest) (Ind (Reg32 source)) = x86_cmov_membase x86_cc_po False dest source 0--> class Cmovz a b where->   cmovz :: a -> b -> CodeGen e s ()--> instance Cmovz Reg32 Reg32 where->   cmovz (Reg32 dest) (Reg32 source) = x86_cmov_reg x86_cc_z False dest source->-> instance Cmovz Reg32 Addr where->   cmovz (Reg32 dest) (Addr source) = x86_cmov_mem x86_cc_z False dest source->-> instance Cmovz Reg32 (Disp, Reg32) where->   cmovz (Reg32 dest) (Disp disp, Reg32 source) = x86_cmov_membase x86_cc_z False dest source disp->-> instance Cmovz Reg32 Ind where->   cmovz (Reg32 dest) (Ind (Reg32 source)) = x86_cmov_membase x86_cc_z False dest source 0--> class Cmovg a b where->   cmovg :: a -> b -> CodeGen e s ()--> instance Cmovg Reg32 Reg32 where->   cmovg (Reg32 dest) (Reg32 source) = x86_cmov_reg x86_cc_gt True dest source->-> instance Cmovg Reg32 Addr where->   cmovg (Reg32 dest) (Addr source) = x86_cmov_mem x86_cc_gt True dest source->-> instance Cmovg Reg32 (Disp, Reg32) where->   cmovg (Reg32 dest) (Disp disp, Reg32 source) = x86_cmov_membase x86_cc_gt True dest source disp->-> instance Cmovg Reg32 Ind where->   cmovg (Reg32 dest) (Ind (Reg32 source)) = x86_cmov_membase x86_cc_gt True dest source 0--> class Cmovge a b where->   cmovge :: a -> b -> CodeGen e s ()--> instance Cmovge Reg32 Reg32 where->   cmovge (Reg32 dest) (Reg32 source) = x86_cmov_reg x86_cc_ge True dest source->-> instance Cmovge Reg32 Addr where->   cmovge (Reg32 dest) (Addr source) = x86_cmov_mem x86_cc_ge True dest source->-> instance Cmovge Reg32 (Disp, Reg32) where->   cmovge (Reg32 dest) (Disp disp, Reg32 source) = x86_cmov_membase x86_cc_ge True dest source disp->-> instance Cmovge Reg32 Ind where->   cmovge (Reg32 dest) (Ind (Reg32 source)) = x86_cmov_membase x86_cc_ge True dest source 0--> class Cmovl a b where->   cmovl :: a -> b -> CodeGen e s ()--> instance Cmovl Reg32 Reg32 where->   cmovl (Reg32 dest) (Reg32 source) = x86_cmov_reg x86_cc_lt True dest source->-> instance Cmovl Reg32 Addr where->   cmovl (Reg32 dest) (Addr source) = x86_cmov_mem x86_cc_lt True dest source->-> instance Cmovl Reg32 (Disp, Reg32) where->   cmovl (Reg32 dest) (Disp disp, Reg32 source) = x86_cmov_membase x86_cc_lt True dest source disp->-> instance Cmovl Reg32 Ind where->   cmovl (Reg32 dest) (Ind (Reg32 source)) = x86_cmov_membase x86_cc_lt True dest source 0--> class Cmovle a b where->   cmovle :: a -> b -> CodeGen e s ()--> instance Cmovle Reg32 Reg32 where->   cmovle (Reg32 dest) (Reg32 source) = x86_cmov_reg x86_cc_le True dest source->-> instance Cmovle Reg32 Addr where->   cmovle (Reg32 dest) (Addr source) = x86_cmov_mem x86_cc_le True dest source->-> instance Cmovle Reg32 (Disp, Reg32) where->   cmovle (Reg32 dest) (Disp disp, Reg32 source) = x86_cmov_membase x86_cc_le True dest source disp->-> instance Cmovle Reg32 Ind where->   cmovle (Reg32 dest) (Ind (Reg32 source)) = x86_cmov_membase x86_cc_le True dest source 0--> class Cmovng a b where->   cmovng :: a -> b -> CodeGen e s ()--> instance Cmovng Reg32 Reg32 where->   cmovng (Reg32 dest) (Reg32 source) = x86_cmov_reg x86_cc_le True dest source->-> instance Cmovng Reg32 Addr where->   cmovng (Reg32 dest) (Addr source) = x86_cmov_mem x86_cc_le True dest source->-> instance Cmovng Reg32 (Disp, Reg32) where->   cmovng (Reg32 dest) (Disp disp, Reg32 source) = x86_cmov_membase x86_cc_le True dest source disp->-> instance Cmovng Reg32 Ind where->   cmovng (Reg32 dest) (Ind (Reg32 source)) = x86_cmov_membase x86_cc_le True dest source 0--> class Cmovnge a b where->   cmovnge :: a -> b -> CodeGen e s ()--> instance Cmovnge Reg32 Reg32 where->   cmovnge (Reg32 dest) (Reg32 source) = x86_cmov_reg x86_cc_lt True dest source->-> instance Cmovnge Reg32 Addr where->   cmovnge (Reg32 dest) (Addr source) = x86_cmov_mem x86_cc_lt True dest source->-> instance Cmovnge Reg32 (Disp, Reg32) where->   cmovnge (Reg32 dest) (Disp disp, Reg32 source) = x86_cmov_membase x86_cc_lt True dest source disp->-> instance Cmovnge Reg32 Ind where->   cmovnge (Reg32 dest) (Ind (Reg32 source)) = x86_cmov_membase x86_cc_lt True dest source 0--> class Cmovnl a b where->   cmovnl :: a -> b -> CodeGen e s ()--> instance Cmovnl Reg32 Reg32 where->   cmovnl (Reg32 dest) (Reg32 source) = x86_cmov_reg x86_cc_ge True dest source->-> instance Cmovnl Reg32 Addr where->   cmovnl (Reg32 dest) (Addr source) = x86_cmov_mem x86_cc_ge True dest source->-> instance Cmovnl Reg32 (Disp, Reg32) where->   cmovnl (Reg32 dest) (Disp disp, Reg32 source) = x86_cmov_membase x86_cc_ge True dest source disp->-> instance Cmovnl Reg32 Ind where->   cmovnl (Reg32 dest) (Ind (Reg32 source)) = x86_cmov_membase x86_cc_ge True dest source 0--> class Cmovnle a b where->   cmovnle :: a -> b -> CodeGen e s ()--> instance Cmovnle Reg32 Reg32 where->   cmovnle (Reg32 dest) (Reg32 source) = x86_cmov_reg x86_cc_gt True dest source->-> instance Cmovnle Reg32 Addr where->   cmovnle (Reg32 dest) (Addr source) = x86_cmov_mem x86_cc_gt True dest source->-> instance Cmovnle Reg32 (Disp, Reg32) where->   cmovnle (Reg32 dest) (Disp disp, Reg32 source) = x86_cmov_membase x86_cc_gt True dest source disp->-> instance Cmovnle Reg32 Ind where->   cmovnle (Reg32 dest) (Ind (Reg32 source)) = x86_cmov_membase x86_cc_gt True dest source 0--> class Cmovno a b where->   cmovno :: a -> b -> CodeGen e s ()--> instance Cmovno Reg32 Reg32 where->   cmovno (Reg32 dest) (Reg32 source) = x86_cmov_reg x86_cc_no True dest source->-> instance Cmovno Reg32 Addr where->   cmovno (Reg32 dest) (Addr source) = x86_cmov_mem x86_cc_no True dest source->-> instance Cmovno Reg32 (Disp, Reg32) where->   cmovno (Reg32 dest) (Disp disp, Reg32 source) = x86_cmov_membase x86_cc_no True dest source disp->-> instance Cmovno Reg32 Ind where->   cmovno (Reg32 dest) (Ind (Reg32 source)) = x86_cmov_membase x86_cc_no True dest source 0--> class Cmovns a b where->   cmovns :: a -> b -> CodeGen e s ()--> instance Cmovns Reg32 Reg32 where->   cmovns (Reg32 dest) (Reg32 source) = x86_cmov_reg x86_cc_ns True dest source->-> instance Cmovns Reg32 Addr where->   cmovns (Reg32 dest) (Addr source) = x86_cmov_mem x86_cc_ns True dest source->-> instance Cmovns Reg32 (Disp, Reg32) where->   cmovns (Reg32 dest) (Disp disp, Reg32 source) = x86_cmov_membase x86_cc_ns True dest source disp->-> instance Cmovns Reg32 Ind where->   cmovns (Reg32 dest) (Ind (Reg32 source)) = x86_cmov_membase x86_cc_ns True dest source 0--> class Cmovo a b where->   cmovo :: a -> b -> CodeGen e s ()--> instance Cmovo Reg32 Reg32 where->   cmovo (Reg32 dest) (Reg32 source) = x86_cmov_reg x86_cc_o True dest source->-> instance Cmovo Reg32 Addr where->   cmovo (Reg32 dest) (Addr source) = x86_cmov_mem x86_cc_o True dest source->-> instance Cmovo Reg32 (Disp, Reg32) where->   cmovo (Reg32 dest) (Disp disp, Reg32 source) = x86_cmov_membase x86_cc_o True dest source disp->-> instance Cmovo Reg32 Ind where->   cmovo (Reg32 dest) (Ind (Reg32 source)) = x86_cmov_membase x86_cc_o True dest source 0--> class Cmovs a b where->   cmovs :: a -> b -> CodeGen e s ()--> instance Cmovs Reg32 Reg32 where->   cmovs (Reg32 dest) (Reg32 source) = x86_cmov_reg x86_cc_s True dest source->-> instance Cmovs Reg32 Addr where->   cmovs (Reg32 dest) (Addr source) = x86_cmov_mem x86_cc_s True dest source->-> instance Cmovs Reg32 (Disp, Reg32) where->   cmovs (Reg32 dest) (Disp disp, Reg32 source) = x86_cmov_membase x86_cc_s True dest source disp->-> instance Cmovs Reg32 Ind where->   cmovs (Reg32 dest) (Ind (Reg32 source)) = x86_cmov_membase x86_cc_s True dest source 0---release stack frame--> leave :: CodeGen e s ()-> leave = x86_leave---store ah into flags--> sahf :: CodeGen e s ()-> sahf = x86_sahf
Harpy/X86CGCombinators.hs view
@@ -19,6 +19,8 @@   -- * Types   UserState(..),   UserEnv(..),+  emptyUserEnv,+  emptyUserState,   CtrlDest(..),   DataDest(..),   -- * Combinators@@ -26,24 +28,26 @@   doWhile,   continue,   continueBranch,+  saveRegs,+  function,   withDataDest,   withCtrlDest,   withDest,-  function,-  withRegister-  ) where+   ) where  import Text.PrettyPrint.HughesPJ  import Foreign+import Data.Word  import Harpy.CodeGenMonad import Harpy.X86CodeGen+import Harpy.X86Assembler  -- | Destination for a calculated value.-data DataDest = RegDest Word8            -- ^ Store into specific register+data DataDest = RegDest Reg32            -- ^ Store into specific register               | StackDest                -- ^ Push onto stack-              | MemBaseDest Word8 Word32 -- ^ Store at memory address+              | MemBaseDest Reg32 Word32 -- ^ Store at memory address               | Ignore                   -- ^ Throw result away.  -- | Destination for control transfers@@ -54,18 +58,19 @@                                          -- depending on outcome of test  -- | User state is used to maintain bitmask of registers currently in use.-data UserState = UserState { usedRegs :: Int}+data UserState = UserState {}                                -- | User environment stores code generators for accessing specific -- variables as well as the current data and control destinations-data UserEnv = UserEnv { bindings :: [(String, -                                       CodeGen UserEnv UserState ())],+data UserEnv = UserEnv { bindings :: [(String, CodeGen UserEnv UserState ())],                          dataDest :: DataDest,                          ctrlDest :: CtrlDest } -emptyUserState = UserState{usedRegs = 0}+emptyUserState :: UserState+emptyUserState = UserState{} +emptyUserEnv :: UserEnv emptyUserEnv = UserEnv{bindings = [], dataDest = Ignore,                        ctrlDest = Return} @@ -77,35 +82,48 @@     do env <- getEnv         elseLabel <- newLabel        endLabel <- newLabel-       withDest Ignore (Branch FallThrough (Goto elseLabel)) -         (condCg)+       withDest Ignore (Branch FallThrough (Goto elseLabel)) condCg        withCtrlDest (case ctrlDest env of                         FallThrough -> Goto endLabel                        _ -> ctrlDest env)                     (thenCg >> continue)-       defineLabel elseLabel-       elseCg >> continue-       defineLabel endLabel+       elseLabel @@ (elseCg >> continue)+       endLabel @@ return ()  doWhile :: CodeGen UserEnv s r -> CodeGen UserEnv s a -> CodeGen UserEnv s () doWhile condCg bodyCg =     do topLabel <- newLabel        testLabel <- newLabel-       emitFixup testLabel 1 Fixup8-       x86_jump8 0-       defineLabel topLabel-       withCtrlDest FallThrough (bodyCg >> continue)-       defineLabel testLabel-       withDest Ignore (Branch (Goto topLabel) FallThrough) condCg +       jmp testLabel+       topLabel @@ withCtrlDest FallThrough (bodyCg >> continue)+       testLabel @@ withDest Ignore (Branch (Goto topLabel) FallThrough) +                        condCg         continue +doFor :: (Mov a Word32, Add a Word32, Cmp a Word32) => a -> Word32 -> Word32 -> Int32 ->+         CodeGen UserEnv s r ->+         CodeGen UserEnv s ()+doFor loc from to step body =+    do topLabel <- newLabel+       testLabel <- newLabel+       mov loc from+       jmp testLabel+       topLabel @@ withCtrlDest FallThrough  (body >> continue)+       testLabel @@ cmp loc to+       add loc (fromIntegral step :: Word32)+       if step < 0+          then jge topLabel+          else jle topLabel+       continue+       + continue :: CodeGen UserEnv s () continue =     do env <- getEnv        cont (ctrlDest env)   where   cont FallThrough = return ()-  cont (Goto l) = emitFixup l 1 Fixup32 >> x86_jump32 0+  cont (Goto l) = jmp l   cont (Branch _ _) = error "Branch in continue"   cont Return = x86_epilog 0 @@ -117,23 +135,23 @@        cont cc isSigned c1 c2   where   cont cc isSigned (Goto l1) (Goto l2) =-    do emitFixup l1 1 Fixup32-       x86_branch32 cc 0 isSigned-       emitFixup l2 1 Fixup32+    do x86_branch32 cc 0 isSigned+       emitFixup l1 (-4) Fixup32        x86_branch32 (negateCC cc) 0 isSigned+       emitFixup l2 (-4) Fixup32   cont cc isSigned (Goto l1) FallThrough =-    do emitFixup l1 1 Fixup32-       x86_branch32 cc 0 isSigned+    do x86_branch32 cc 0 isSigned+       emitFixup l1 (-4) Fixup32   cont cc isSigned FallThrough (Goto l2) =-    do emitFixup l2 1 Fixup32-       x86_branch32 (negateCC cc) 0 isSigned+    do x86_branch32 (negateCC cc) 0 isSigned+       emitFixup l2 (-4) Fixup32   cont cc isSigned (Goto l1) Return =-    do emitFixup l1 1 Fixup32-       x86_branch32 cc 0 isSigned+    do x86_branch32 cc 0 isSigned+       emitFixup l1 (-4) Fixup32        withCtrlDest Return continue   cont cc isSigned Return (Goto l2) =-    do emitFixup l2 1 Fixup32-       x86_branch32 (negateCC cc) 0 isSigned+    do x86_branch32 (negateCC cc) 0 isSigned+       emitFixup l2 (-4) Fixup32        withCtrlDest Return continue   cont _ _ _ _ = error "unhandled case in continueBranch" @@ -143,12 +161,12 @@   where   reg' sreg (RegDest r) =      do if sreg /= r -          then x86_mov_reg_reg r sreg x86_dword_size +          then mov r sreg           else return ()   reg' sreg (StackDest) = -    do x86_push_reg sreg+    do push sreg   reg' sreg (MemBaseDest r offset) = -    do x86_mov_membase_reg r offset sreg x86_dword_size+    do mov (Disp offset, r) sreg   reg' sreg Ignore = return ()   membase reg ofs =@@ -156,12 +174,14 @@        membase' reg ofs (dataDest env)   where   membase' reg ofs (RegDest r) = -    do x86_mov_reg_membase r reg ofs x86_dword_size+    do mov r (Disp ofs, reg)   membase' reg ofs (StackDest) = -    do x86_push_membase reg ofs+    do push (Disp ofs, reg)   membase' reg ofs (MemBaseDest r offset) = -    do x86_mov_reg_membase x86_edi reg ofs x86_dword_size-       x86_mov_membase_reg r offset x86_edi x86_dword_size+    do push edi+       mov edi (Disp ofs, reg)+       mov (Disp offset, r) edi+       pop edi   membase' reg ofs Ignore = return ()   global ofs =@@ -169,12 +189,14 @@        global' ofs (dataDest env)   where   global' ofs (RegDest r) = -    do x86_mov_reg_mem r ofs x86_dword_size+    do mov r (Addr ofs)   global' ofs (StackDest) = -    do x86_push_mem ofs+    do push (Addr ofs)   global' ofs (MemBaseDest r offset) = -    do x86_mov_reg_mem x86_edi ofs x86_dword_size-       x86_mov_membase_reg r offset x86_edi x86_dword_size+    do push edi+       mov edi (Addr ofs)+       mov (Disp offset, r) edi+       pop edi   global' ofs Ignore = return ()  immediate value =@@ -182,38 +204,30 @@        immediate' value (dataDest env)   where   immediate' value (RegDest r) = -    do x86_mov_reg_imm r value+    do mov r value   immediate' value (StackDest) =      do x86_push_imm value   immediate' value (MemBaseDest r offset) = -    do x86_mov_reg_imm x86_edi value -       x86_mov_membase_reg r offset x86_edi x86_dword_size+    do push edi+       mov edi value +       mov (Disp offset, r) edi+       pop edi   immediate' ofs Ignore = return ()  -- | Save a number of registers on the stack, perform the given code -- generation, and restore the registers.-saveRegs :: (Bits a) =>-	    a -> CodeGen UserEnv s r -> CodeGen UserEnv s ()-saveRegs reg_mask cg =-    do gen_push 0 1+saveRegs :: [Reg32] -> CodeGen UserEnv s r -> CodeGen UserEnv s ()+saveRegs [] cg = cg >> return ()+saveRegs regs cg =+    do gen_push regs        withCtrlDest FallThrough cg-       gen_pop x86_edi (1 `shiftL` (fromIntegral x86_edi))+       gen_pop regs        continue   where-  gen_push i m =-     if i <= x86_edi-        then do if (reg_mask .&. m) /= 0-                   then x86_push_reg i-                   else return ()-                gen_push (i + 1) (m `shiftL` 1)-        else return ()-  gen_pop i m =-    if m /= 0-       then do if (reg_mask .&. m) /= 0-                  then x86_pop_reg i-                  else return ()-               gen_pop (i - 1) (m `shiftR` 1)-       else return ()+  gen_push [] = return ()+  gen_push (r:regs) = push r >> gen_push regs+  gen_pop [] = return ()+  gen_pop (r:regs) = gen_pop regs >> pop r  -- | Perform the code generation associated with the variable given. loadVar :: String -> CodeGen UserEnv UserState ()@@ -223,18 +237,6 @@          Just cg -> cg          Nothing -> failCodeGen (text ("undefined variable: " ++ name)) --- | Find a register not recorded in the given bit mask.-findReg :: (Bits a) => a -> Word8-findReg reg_mask = findR 0 1-  where-   findR i m =-     if i <= x86_edi-        then if (reg_mask .&. m) == 0-                   then i-                   else findR (i + 1) (m `shiftL` 1)-        else error "no register left for allocation"-    - -- | Set the data destinations to the given values while -- running the code generator. withDataDest :: DataDest -> CodeGen UserEnv s r -> CodeGen UserEnv s r@@ -261,16 +263,4 @@ function :: CodeGen UserEnv s r -> CodeGen UserEnv s r function cg =     do x86_prolog 0 0-       withDataDest (RegDest x86_eax) $ withCtrlDest Return $ cg---- | Apply the given cg to a register, which is reserved while the--- generator is running.-withRegister :: (Word8 -> CodeGen e UserState t) -> CodeGen e UserState ()-withRegister cg =-    do state <- getState-       let used = usedRegs state-       let reg = findReg used-       setState (state{usedRegs = used .|. (1 `shiftL` fromIntegral reg)})-       cg reg-       state <- getState-       setState (state{usedRegs = used})+       withDest (RegDest eax) Return $ cg
Harpy/X86CodeGen.hs view
@@ -45,38 +45,68 @@ --------------------------------------------------------------------------  module Harpy.X86CodeGen(+    -- * Types+    X86_SSE_PFX,     -- * Constants     -- ** Machine characteristics+    -- |  Sizes of various machine data types in bytes.     x86_dword_size,      x86_qword_size, +    x86_max_instruction_bytes,     -- ** Register numbers     -- | x86 general-purpose register numbers     x86_eax, x86_ecx, x86_edx, x86_ebx, x86_esp, x86_ebp, x86_esi, x86_edi,     x86_nobasereg,     -- ** Register masks and predicates+    -- | Bitvector masks for general-purpose registers     x86_eax_mask, x86_ecx_mask, x86_edx_mask, x86_ebx_mask,-    x86_esi_mask, x86_edi_mask, +    x86_esi_mask, x86_edi_mask, x86_ebp_mask,     x86_callee_regs, x86_caller_regs, x86_byte_regs,     -- ** ALU operations+    -- | Opcodes for ALU instructions     x86_add, x86_or, x86_adc, x86_sbb, x86_and, x86_sub, x86_xor, x86_cmp,     -- ** Shift operations+    -- | Opcodes for shift instructions     x86_rol, x86_ror, x86_rcl, x86_rcr, x86_shl,-    x86_shr, x86_sar,+    x86_shr, x86_sar, x86_shld, x86_shlr,+    -- ** FP operations+    -- | Opcodes for floating-point instructions+    x86_fadd, x86_fmul, x86_fcom, x86_fcomp, x86_fsub, x86_fsubr,+    x86_fdiv, x86_fdivr,+    -- ** FP conditions and control codes+    -- | FP status word codes+    x86_fp_c0, x86_fp_c1, x86_fp_c2, x86_fp_c3, x86_fp_cc_mask,+    -- | FP control word codes+    x86_fpcw_invopex_mask, x86_fpcw_denopex_mask, x86_fpcw_zerodiv_mask, +    x86_fpcw_ovfex_mask, x86_fpcw_undfex_mask, x86_fpcw_precex_mask, +    x86_fpcw_precc_mask, x86_fpcw_roundc_mask,+    x86_fpcw_prec_single, x86_fpcw_prec_double, +    x86_fpcw_prec_extended,+    x86_fpcw_round_nearest, x86_fpcw_round_down, x86_fpcw_round_up,+    x86_fpcw_round_tozero,     -- ** Condition codes+    -- | Integer conditions codes     x86_cc_eq, x86_cc_e, x86_cc_z,     x86_cc_ne, x86_cc_nz,     x86_cc_lt, x86_cc_b, x86_cc_c, x86_cc_nae, x86_cc_le, x86_cc_be,      x86_cc_na, x86_cc_gt, x86_cc_a, x86_cc_nbe, x86_cc_ge, x86_cc_ae,      x86_cc_nb, x86_cc_nc, x86_cc_lz, x86_cc_s, x86_cc_gez, x86_cc_ns,      x86_cc_p, x86_cc_np, x86_cc_pe, x86_cc_po, x86_cc_o, x86_cc_no,+    -- ** Instruction prefix codes+    x86_lock_prefix, x86_repnz_prefix, x86_repz_prefix, x86_rep_prefix,+    x86_cs_prefix, x86_ss_prefix, x86_ds_prefix, x86_es_prefix,+    x86_fs_prefix, x86_gs_prefix, x86_unlikely_prefix,+    x86_likely_prefix, x86_operand_prefix, x86_address_prefix,     -- * Functions     -- ** Utility functions     x86_is_scratch, x86_is_callee,     -- ** Code emission-    x86_imm_emit32, x86_imm_emit16, x86_imm_emit8, +    -- | These functions are used to emit parts of instructions, such+    -- as constants or operand descriptions.+    x86_imm_emit16, x86_imm_emit8, x86_imm_emit32,      x86_membase_emit, x86_alu_reg_imm,     -- ** Call instructions-    x86_call_hs, x86_call_membase, x86_call_mem, x86_call_reg, +    x86_call_hs, x86_call_membase, x86_call_mem, x86_call_reg, x86_call_code,     x86_call_imm,     -- ** Function prologue and epilogue     x86_prolog, x86_epilog, x86_enter, x86_leave,@@ -130,16 +160,42 @@     -- ** Conversion      x86_cdq,x86_widen_memindex, x86_widen_membase, x86_widen_mem,      x86_widen_reg,+    -- ** Floating point+    x86_fp_op_mem, x86_fp_op_membase, x86_fp_op, x86_fp_op_reg,+    x86_fp_int_op_membase, x86_fstp, x86_fcompp, x86_fucompp,+    x86_fnstsw, x86_fnstcw, x86_fnstcw_membase,+    x86_fldcw, x86_fldcw_membase, x86_fchs,+    x86_frem, x86_fxch, x86_fcomi, x86_fcomip, x86_fucomi, x86_fucomip,+    x86_fld, x86_fld_membase, x86_fld80_mem, x86_fld80_membase,+    x86_fld_reg, x86_fldz, x86_fld1, x86_fldpi,+    x86_fst, x86_fst_membase, x86_fst80_mem, x86_fst80_membase,+    x86_fist_pop, x86_fist_pop_membase, x86_fstsw, +    x86_fist_membase, x86_fild, x86_fild_membase,+    x86_fsin, x86_fcos, x86_fabs, x86_ftst, x86_fxam, x86_fpatan, +    x86_fprem, x86_fprem1, x86_frndint, x86_fsqrt, x86_fptan,+    -- ** SSE instructions+    x86_sse_ps, x86_sse_pd, x86_sse_ss, x86_sse_sd,+    x86_add_sse_reg_reg, x86_add_sse_reg_mem, x86_add_sse_reg_membase,+    x86_sub_sse_reg_reg, x86_sub_sse_reg_mem, x86_sub_sse_reg_membase,+    x86_mul_sse_reg_reg, x86_mul_sse_reg_mem, x86_mul_sse_reg_membase,+    x86_div_sse_reg_reg, x86_div_sse_reg_mem, x86_div_sse_reg_membase,+    x86_max_sse_reg_reg, x86_max_sse_reg_mem, x86_max_sse_reg_membase,+    x86_min_sse_reg_reg, x86_min_sse_reg_mem, x86_min_sse_reg_membase,+    x86_sqrt_sse_reg_reg, x86_sqrt_sse_reg_mem, x86_sqrt_sse_reg_membase,+    x86_mov_sse_reg_reg, x86_mov_sse_reg_mem, x86_mov_sse_reg_membase, x86_mov_sse_mem_reg ,x86_mov_sse_membase_reg,+    x86_ucomisd_reg_reg, x86_ucomisd_reg_mem, x86_ucomisd_reg_membase,+    x86_ucomiss_reg_reg, x86_ucomiss_reg_mem, x86_ucomiss_reg_membase,+    x86_comisd_reg_reg, x86_comisd_reg_mem, x86_comisd_reg_membase,+    x86_comiss_reg_reg, x86_comiss_reg_mem, x86_comiss_reg_membase,     -- ** Miscellaneous     x86_sahf, x86_wait, x86_nop, x86_breakpoint, x86_rdtsc, x86_cld,+    x86_prefix, x86_padding,     -- ** Other utilities     negateCC                        ) where  import qualified Text.PrettyPrint.HughesPJ as PP -import Debug.Trace- import Data.Word import Data.Bits @@ -147,8 +203,10 @@  import Harpy.CodeGenMonad +-- | Maximal length of an x86 instruction in bytes.+x86_max_instruction_bytes :: Int+x86_max_instruction_bytes = 16   -- According to Intel manual. --- |  Sizes of various machine data types in bytes. x86_dword_size, x86_qword_size :: Int  x86_dword_size = 4                    -- Number of bytes in doubleword@@ -165,7 +223,6 @@ x86_esi = 6 x86_edi = 7 --- | Opcodes for ALU instructions x86_cmp, x86_or, x86_adc, x86_sbb, x86_and, x86_sub, x86_xor,    x86_add :: Word8 x86_add = 0@@ -177,7 +234,6 @@ x86_xor = 6 x86_cmp = 7 --- | Opcodes for shift instructions x86_sar, x86_shld, x86_shlr, x86_rol, x86_ror, x86_rcl, x86_rcr,   x86_shl, x86_shr :: Word8 @@ -191,8 +247,6 @@ x86_shr  = 5 x86_sar  = 7 --- | Opcodes for floating-point instructions- x86_fadd, x86_fmul, x86_fcom, x86_fcomp, x86_fsub, x86_fsubr :: Word8 x86_fdiv, x86_fdivr :: Word8 @@ -205,7 +259,6 @@ x86_fdiv  = 6 x86_fdivr = 7 --- | Integer conditions codes x86_cc_no, x86_cc_eq, x86_cc_e, x86_cc_z, x86_cc_ne, x86_cc_nz, x86_cc_lt :: Int x86_cc_b, x86_cc_c, x86_cc_nae, x86_cc_le, x86_cc_be, x86_cc_na :: Int x86_cc_gt :: Int@@ -300,6 +353,7 @@ x86_address_prefix = 0x67  -- | Mapping from condition code to opcode (unsigned)+x86_cc_unsigned_map :: [Word8] x86_cc_unsigned_map = [        0x74, -- eq          0x75, -- ne  @@ -316,6 +370,7 @@  ]  -- | Mapping from condition code to opcode (signed)+x86_cc_signed_map :: [Word8] x86_cc_signed_map = [       0x74, -- eq         0x75, -- ne  @@ -332,6 +387,7 @@  ]  -- | Mapping from condition code to negated condition code.+x86_cc_negate :: [(Int, Int)] x86_cc_negate = [        (x86_cc_eq, x86_cc_ne), -- eq          (x86_cc_ne, x86_cc_eq), -- ne  @@ -359,7 +415,6 @@ x86_nobasereg :: Word8 x86_nobasereg = (-1) --- | Bitvector masks for general-purpose registers x86_edi_mask, x86_esi_mask, x86_ebx_mask, x86_ebp_mask,     x86_eax_mask, x86_ecx_mask, x86_edx_mask:: Int x86_esi_mask = (1 `shiftL` (fromIntegral x86_esi))@@ -408,10 +463,12 @@ -- useful building blocks  -x86_modrm_mod modrm = ((modrm) `shiftR` 6)-x86_modrm_reg modrm = (((modrm) `shiftR` 3) .&. 0x7)-x86_modrm_rm modrm = ((modrm) .&. 0x7)+--x86_modrm_mod modrm = ((modrm) `shiftR` 6)+--x86_modrm_reg :: Bits a => a -> a+--x86_modrm_reg modrm = (((modrm) `shiftR` 3) .&. 0x7)+--x86_modrm_rm modrm = ((modrm) .&. 0x7) +x86_address_byte :: Word8 -> Word8 -> Word8 -> CodeGen e s () x86_address_byte m o r = emit8 ((((m) .&. 0x03) `shiftL` 6) .|.                                (((o) .&. 0x07) `shiftL` 3) .|.                                  (((r) .&. 0x07)))@@ -420,8 +477,9 @@ x86_imm_emit32 :: Word32 -> CodeGen e s () x86_imm_emit32 imm = emit32 imm --- | Emit a 32-bit constant to the instruction stream at the given offset.-x86_imm_emit32_at pos imm = emit32At pos imm+-- -- | Emit a 32-bit constant to the instruction stream at the given offset.+-- x86_imm_emit32_at :: Int -> Word32 -> CodeGen e s ()+-- x86_imm_emit32_at pos imm = emit32At pos imm  -- | Emit a 16-bit constant to the instruction stream. x86_imm_emit16 :: Word16 -> CodeGen e s ()@@ -436,16 +494,21 @@ x86_imm_emit8 imm =    emit8 (imm .&. 0xff) --- | Emit a 8-bit constant to the instruction stream at the given offset.-x86_imm_emit8_at pos imm = -  emit8At pos (imm .&. 0xff)+-- -- | Emit a 8-bit constant to the instruction stream at the given offset.+-- x86_imm_emit8_at :: Int -> Word8 -> CodeGen e s ()+-- x86_imm_emit8_at pos imm = emit8At pos (imm .&. 0xff)  -- | Return true if the given value is a signed 8-bit constant.+x86_is_imm8 :: Integral a => a -> Bool x86_is_imm8 imm =  (((fromIntegral imm :: Integer) >= -128) && ((fromIntegral imm :: Integer) <= 127))-x86_is_imm16 imm = (((fromIntegral imm :: Integer) >= -(1 `shiftL` 16)) && -                              ((fromIntegral imm :: Integer) <= ((1 `shiftL` 16)-1)))+-- x86_is_imm16 :: Integral a => a -> Bool+-- x86_is_imm16 imm = (((fromIntegral imm :: Integer) >= -(1 `shiftL` 16)) && +--                               ((fromIntegral imm :: Integer) <= ((1 `shiftL` 16)-1))) +x86_reg_emit :: Word8 -> Word8 -> CodeGen e s () x86_reg_emit r regno = x86_address_byte 3 r regno++x86_reg8_emit :: Word8 -> Word8 -> Bool -> Bool -> CodeGen e s () x86_reg8_emit r regno is_rh is_rnoh =    x86_address_byte 3 (if is_rh then (r .|. 4) else r)                       (if is_rnoh then regno .|. 4 else regno)@@ -475,32 +538,34 @@                                x86_imm_emit32 (fromIntegral disp)        else do if (disp == 0 && (toInteger basereg) /= (toInteger x86_ebp))                   then x86_address_byte 0 r basereg-                  else if x86_is_imm8 (fromIntegral disp)+                  else if x86_is_imm8 (fromIntegral disp :: Word32)                           then do x86_address_byte 1 r basereg                                   x86_imm_emit8 (fromIntegral disp)                           else do x86_address_byte 2 r basereg                                   x86_imm_emit32 (fromIntegral disp) -x86_memindex_emit r basereg disp indexreg shift =+x86_memindex_emit :: Word8 -> Word8 -> Word32 -> Word8 -> Word8 -> CodeGen e s ()+x86_memindex_emit r basereg disp indexreg shft =     if (basereg == x86_nobasereg)        then do x86_address_byte 0 r 4-               x86_address_byte shift indexreg 5+               x86_address_byte shft indexreg 5                x86_imm_emit32 disp        else if ((disp) == 0 && (basereg) /= x86_ebp)                then do x86_address_byte 0 r 4-                       x86_address_byte shift indexreg (fromIntegral basereg)+                       x86_address_byte shft indexreg (fromIntegral basereg)                 else if x86_is_imm8 disp                         then do x86_address_byte 1 r 4-                                x86_address_byte shift indexreg +                                x86_address_byte shft indexreg                                               (fromIntegral basereg)                                 x86_imm_emit8 (fromIntegral disp)                         else do x86_address_byte 2 r 4-                                x86_address_byte shift indexreg 5+                                x86_address_byte shft indexreg 5                                 x86_imm_emit32 disp +{- x86_jmp_ofs_size ins =   do instr <- peek8At ins-     case trace (show instr) instr of+     case instr of        0xe8 -> return 1        0xe9 -> return 1        0x0f ->@@ -509,6 +574,7 @@                then failCodeGen (PP.text "Wrong Opcode")                else return 1        _ -> return 0+-}  -- target is the position in the code where to jump to: @@ -527,6 +593,7 @@ -- the instruction is inspected for validity and the correct displacement -- is inserted. +{- x86_patch ins target =     let pos = ins + 1     in do size <- x86_jmp_ofs_size ins@@ -537,6 +604,7 @@              else if (x86_is_imm8 (disp - 1))                       then x86_imm_emit8_at pos (fromIntegral (disp - 1))                      else failCodeGen (PP.text "Wrong offset")+-}  x86_breakpoint, x86_cld, x86_stosb, x86_stosl, x86_stosd, x86_movsb,   x86_movsl, x86_movsd :: CodeGen s e ()@@ -555,13 +623,20 @@ x86_rdtsc :: CodeGen s e () x86_rdtsc = emit8 0x0f >> emit8 0x31 +x86_cmpxchg_reg_reg :: Word8 -> Word8 -> CodeGen e s () x86_cmpxchg_reg_reg dreg reg =      emit8 0x0f >> emit8 0xb1 >> x86_reg_emit reg dreg++x86_cmpxchg_mem_reg :: Word32 -> Word8 -> CodeGen e s () x86_cmpxchg_mem_reg mem reg = emit8 0x0f >> emit8 0xb1 >> x86_mem_emit reg mem++x86_cmpxchg_membase_reg :: Word8 -> Word32 -> Word8 -> CodeGen e s () x86_cmpxchg_membase_reg basereg disp reg =     emit8 0x0f >> emit8 0xb1 >> x86_membase_emit reg basereg disp +x86_xchg :: Num a => a -> CodeGen e s () x86_xchg size = if size == 1 then emit8 0x86 else emit8 0x87+ x86_xchg_reg_reg dreg reg size =     do x86_xchg size ; x86_reg_emit reg dreg x86_xchg_mem_reg mem reg size =@@ -569,8 +644,8 @@ x86_xchg_membase_reg basereg disp reg size =     do x86_xchg size ; x86_membase_emit reg basereg disp -x86_xadd size = -    do emit8 0x0f ; if size == 1 then emit8 0xc0 else emit8 0xc1+x86_xadd :: Num a => a -> CodeGen e s ()+x86_xadd size = do emit8 0x0f ; if size == 1 then emit8 0xc0 else emit8 0xc1 x86_xadd_reg_reg dreg reg size = x86_xadd size >> x86_reg_emit reg dreg x86_xadd_mem_reg mem reg size = x86_xadd size >> x86_mem_emit reg mem x86_xadd_membase_reg basereg disp reg size =@@ -760,6 +835,7 @@     do emit8 0xf7        x86_membase_emit (6 + (if is_signed then 1 else 0)) basereg disp +x86_mov1 :: Num t => t -> CodeGen e s () x86_mov1 size =     case size of          1 -> emit8 0x88@@ -767,6 +843,7 @@          4 -> emit8 0x89          _ -> failCodeGen (PP.text "invalid operand size")        +x86_mov2 :: Num t => t -> CodeGen e s () x86_mov2 size =     case size of          1 -> emit8 0x8a@@ -782,8 +859,8 @@     do x86_mov2 size ; x86_regp_emit reg regp x86_mov_membase_reg basereg disp reg size =        do x86_mov1 size ; x86_membase_emit reg basereg disp      -x86_mov_memindex_reg basereg disp indexreg shift reg size =   -    do x86_mov1 size ; x86_memindex_emit reg basereg disp indexreg shift+x86_mov_memindex_reg basereg disp indexreg shft reg size =   +    do x86_mov1 size ; x86_memindex_emit reg basereg disp indexreg shft x86_mov_reg_reg dreg reg size =            do x86_mov2 size        x86_reg_emit dreg reg  @@ -793,15 +870,11 @@ x86_mov_reg_membase reg basereg disp size =     do x86_mov2 size        x86_membase_emit reg basereg disp      -x86_mov_reg_memindex reg basereg disp 4 shift size =+x86_mov_reg_memindex _ _ _ 4 _ _ =     failCodeGen $ PP.text "x86_mov_reg_memindex: cannot use (E)SP as index register"-x86_mov_reg_memindex reg basereg disp indexreg shift size =   +x86_mov_reg_memindex reg basereg disp indexreg shft size =        do x86_mov2 size-       x86_memindex_emit reg basereg disp indexreg  shift     ---- Note: x86_clear_reg () changes the condition code!--x86_clear_reg reg = x86_alu_reg_reg x86_xor reg reg+       x86_memindex_emit reg basereg disp indexreg  shft  x86_mov_reg_imm reg imm =          emit8 (0xb8 + reg) >> x86_imm_emit32 imm  @@ -832,28 +905,34 @@                        x86_membase_emit 0 basereg disp                                x86_imm_emit32 imm      -x86_mov_memindex_imm basereg disp indexreg shift imm size =   +x86_mov_memindex_imm basereg disp indexreg shft imm size =        if size == 1     then do emit8 0xc6        -            x86_memindex_emit 0 basereg disp indexreg  shift  +            x86_memindex_emit 0 basereg disp indexreg  shft               x86_imm_emit8 (fromIntegral imm)       else if size == 2          then do emit8 0x66                     emit8 0xc7   -                 x86_memindex_emit 0 basereg disp indexreg  shift     +                 x86_memindex_emit 0 basereg disp indexreg  shft                       x86_imm_emit16 (fromIntegral imm)              else do emit8 0xc7   -                 x86_memindex_emit 0 basereg disp indexreg  shift     +                 x86_memindex_emit 0 basereg disp indexreg  shft                       x86_imm_emit32 imm     -- LEA: Load Effective Address +x86_lea_mem :: Word8 -> Word32 -> CodeGen e s () x86_lea_mem reg mem = emit8 0x8d >> x86_mem_emit reg mem      ++x86_lea_membase :: Word8 -> Word8 -> Word32 -> CodeGen e s () x86_lea_membase reg basereg disp =         emit8 0x8d >> x86_membase_emit reg basereg disp   -x86_lea_memindex reg basereg disp indexreg shift =-    emit8 0x8d >> x86_memindex_emit reg basereg disp indexreg shift    +x86_lea_memindex :: Word8 -> Word8 -> Word32 -> Word8 -> Word8 -> CodeGen e s ()+x86_lea_memindex reg basereg disp indexreg shft =+    emit8 0x8d >> x86_memindex_emit reg basereg disp indexreg shft   ++x86_widen_reg :: Word8 -> Word8 -> Bool -> Bool -> CodeGen e s ()  x86_widen_reg dreg reg is_signed is_half =     if is_half || x86_is_byte_reg reg     then do let op = 0xb6 + (if is_signed then 0x08 else 0) +@@ -862,42 +941,52 @@             emit8 op             x86_reg_emit dreg reg     else failCodeGen (PP.text "widen: need byte register or is_half=True")++x86_widen_mem :: Word8 -> Word32 -> Bool -> Bool -> CodeGen e s () x86_widen_mem dreg mem is_signed is_half =     do let op = 0xb6 + (if is_signed then 0x08 else 0) +                 (if is_half then 0x1 else 0)        emit8 0x0f        emit8 op        x86_mem_emit dreg mem  ++x86_widen_membase :: Word8 -> Word8 -> Word32 -> Bool -> Bool -> CodeGen e s () x86_widen_membase dreg basereg disp is_signed is_half =            do let op = 0xb6 + (if is_signed then 0x08 else 0) +                 (if is_half then 0x1 else 0)        emit8 0x0f        emit8 op        x86_membase_emit dreg basereg disp     -x86_widen_memindex dreg basereg disp indexreg shift is_signed is_half =++x86_widen_memindex :: Word8 -> Word8 -> Word32 -> Word8 -> Word8 -> Bool -> Bool -> CodeGen e s ()+x86_widen_memindex dreg basereg disp indexreg shft is_signed is_half =     do let op = 0xb6 + (if is_signed then 0x08 else 0) +                 (if is_half then 0x1 else 0)        emit8 0x0f        emit8 op-       x86_memindex_emit dreg basereg disp indexreg shift     +       x86_memindex_emit dreg basereg disp indexreg shft       x86_cdq, x86_wait :: CodeGen s e () x86_cdq  = emit8 0x99 x86_wait = emit8 0x9b +x86_fp_op_mem :: Word8 -> Word32 -> Bool -> CodeGen e s () x86_fp_op_mem opc mem is_double =          do emit8 (if is_double then 0xdc else 0xd8)               x86_mem_emit opc mem+x86_fp_op_membase :: Word8 -> Word8 -> Word32 -> Bool -> CodeGen e s () x86_fp_op_membase opc basereg disp is_double =             do emit8 (if is_double then 0xdc else 0xd8)               x86_membase_emit opc basereg disp      +x86_fp_op ::Word8 -> Word8 -> CodeGen e s () x86_fp_op opc index =      do emit8 0xd8        emit8 (0xc0 + (opc `shiftL` 3) + (index .&. 0x07))+x86_fp_op_reg :: Int -> Word8 -> Bool -> CodeGen e s () x86_fp_op_reg opc index pop_stack =   -    do let  map = [ 0, 1, 2, 3, 5, 4, 7, 6, 8]        +    do let  opcMap = [ 0, 1, 2, 3, 5, 4, 7, 6, 8]                emit8 (if pop_stack then 0xde else 0xdc)       -       emit8 (0xc0 + ((map !! opc) `shiftL` 3) + (index .&. 0x07))+       emit8 (0xc0 + ((opcMap !! opc) `shiftL` 3) + (index .&. 0x07))   -- @x86_fp_int_op_membase@@ -906,67 +995,100 @@ -- Operand is addressed by [basereg + disp]. -- is_int specifies whether operand is int32 (TRUE) or int16 (FALSE). +x86_fp_int_op_membase :: Word8 -> Word8 -> Word32 -> Bool -> CodeGen e s () x86_fp_int_op_membase opc basereg disp is_int =     do emit8 (if is_int then 0xda else 0xde)          x86_membase_emit opc basereg disp      +x86_fstp :: Word8 -> CodeGen e s () x86_fstp index =           emit8 0xdd >> emit8 (0xd8 + index)        +x86_fcompp :: CodeGen e s () x86_fcompp = emit8 0xde >> emit8 0xd9 +x86_fucompp :: CodeGen e s () x86_fucompp = emit8 0xda >> emit8 0xe9        +x86_fnstsw :: CodeGen e s () x86_fnstsw = emit8 0xdf >> emit8 0xe0 +x86_fnstcw :: Word32 -> CodeGen e s () x86_fnstcw mem = emit8 0xd9 >> x86_mem_emit 7 mem     +x86_fnstcw_membase :: Word8 -> Word32 -> CodeGen e s () x86_fnstcw_membase basereg disp =          emit8 0xd9 >> x86_membase_emit 7 basereg disp     +x86_fldcw :: Word32 -> CodeGen e s () x86_fldcw mem = emit8 0xd9 >> x86_mem_emit 5 mem      +x86_fldcw_membase :: Word8 -> Word32 -> CodeGen e s () x86_fldcw_membase basereg disp =           emit8 0xd9 >> x86_membase_emit 5 basereg disp     +x86_fchs :: CodeGen e s () x86_fchs = emit8 0xd9 >> emit8 0xe0   +x86_frem :: CodeGen e s () x86_frem = emit8 0xd9 >> emit8 0xf8+x86_fxch :: Word8 -> CodeGen e s () x86_fxch index = emit8 0xd9 >> emit8 (0xc8 + (index .&. 0x07))        +x86_fcomi :: Word8 -> CodeGen e s () x86_fcomi index = emit8 0xdb >> emit8 (0xf0 + (index .&. 0x07))       +x86_fcomip :: Word8 -> CodeGen e s () x86_fcomip index = emit8 0xdf >> emit8 (0xf0 + (index .&. 0x07))      +x86_fucomi :: Word8 -> CodeGen e s () x86_fucomi index = emit8 0xdb >> emit8 (0xe8 + (index .&. 0x07))+x86_fucomip :: Word8 -> CodeGen e s () x86_fucomip index = emit8 0xdf >> emit8 (0xe8 + (index .&. 0x07))+x86_fld :: Word32 -> Bool -> CodeGen e s () x86_fld mem is_double =            do emit8 (if is_double then 0xdd else 0xd9)               x86_mem_emit 0 mem     +x86_fld_membase :: Word8 -> Word32 -> Bool -> CodeGen e s () x86_fld_membase basereg disp is_double =           do emit8 (if is_double then 0xdd else 0xd9)               x86_membase_emit 0 basereg disp        +x86_fld80_mem :: Word32 -> CodeGen e s () x86_fld80_mem mem = emit8 0xdb >> x86_mem_emit 5 mem  +x86_fld80_membase :: Word8 -> Word32 -> CodeGen e s () x86_fld80_membase basereg disp =           emit8 0xdb >> x86_membase_emit 5 basereg disp     +x86_fild :: Word32 -> Bool -> CodeGen e s () x86_fild mem is_long =             if is_long        then emit8 0xdf >> x86_mem_emit 5 mem          else emit8 0xdb >> x86_mem_emit 0 mem  +x86_fild_membase :: Word8 -> Word32 -> Bool -> CodeGen e s () x86_fild_membase basereg disp is_long =            if is_long        then emit8 0xdf >> x86_membase_emit 5 basereg disp             else emit8 0xdb >> x86_membase_emit 0 basereg disp     +x86_fld_reg :: Word8 -> CodeGen e s () x86_fld_reg index =        emit8 0xd9 >> emit8 (0xc0 + (index .&. 0x07))+x86_fldz :: CodeGen e s () x86_fldz = emit8 0xd9 >> emit8 0xee   +x86_fld1 :: CodeGen e s () x86_fld1 = emit8 0xd9 >> emit8 0xe8+x86_fldpi :: CodeGen e s () x86_fldpi = emit8 0xd9 >> emit8 0xeb   +x86_fst :: Word32 -> Bool -> Bool -> CodeGen e s () x86_fst mem is_double pop_stack =          do emit8 (if is_double then 0xdd else 0xd9)        x86_mem_emit (2 + (if pop_stack then 1 else 0)) mem    +x86_fst_membase :: Word8 -> Word32 -> Bool -> Bool -> CodeGen e s () x86_fst_membase basereg disp is_double pop_stack =         do emit8 (if is_double then 0xdd else 0xd9)               x86_membase_emit (2 + (if pop_stack then 1 else 0)) basereg disp+x86_fst80_mem :: Word32 -> CodeGen e s () x86_fst80_mem mem = emit8 0xdb >> x86_mem_emit 7 mem  +x86_fst80_membase :: Word8 -> Word32 -> CodeGen e s () x86_fst80_membase basereg disp =           emit8 0xdb >> x86_membase_emit 7 basereg disp     +x86_fist_pop :: Word32 -> Bool -> CodeGen e s () x86_fist_pop mem is_long =         if is_long        then emit8 0xdf >> x86_mem_emit 7 mem          else emit8 0xdb >> x86_mem_emit 3 mem  +x86_fist_pop_membase :: Word8 -> Word32 -> Bool -> CodeGen e s () x86_fist_pop_membase basereg disp is_long =         if is_long         then emit8 0xdf >> x86_membase_emit 7 basereg disp             else emit8 0xdb >> x86_membase_emit 3 basereg disp    +x86_fstsw :: CodeGen e s () x86_fstsw = emit8 0x9b >> emit8 0xdf >> emit8 0xe0  -- @x86_fist_membase@@ -974,6 +1096,7 @@ -- addressed by [basereg + disp]. -- is_int specifies whether destination is int32 (TRUE) or int16 (FALSE). +x86_fist_membase :: Word8 -> Word32 -> Bool -> CodeGen e s () x86_fist_membase basereg disp is_int =             if is_int        then emit8 0xdb >> x86_membase_emit 2 basereg disp     @@ -981,14 +1104,27 @@  -- PUSH instruction. +x86_push_reg :: Word8 -> CodeGen e s () x86_push_reg reg = emit8 (0x50 + reg) ++x86_push_regp :: Word8 -> CodeGen e s () x86_push_regp reg = emit8 0xff >> x86_regp_emit 6 reg ++x86_push_mem :: Word32 -> CodeGen e s () x86_push_mem mem = emit8 0xff >> x86_mem_emit 6 mem   ++x86_push_membase :: Word8 -> Word32 -> CodeGen e s () x86_push_membase basereg disp =      emit8 0xff >> x86_membase_emit 6 basereg disp     -x86_push_memindex basereg disp indexreg shift =-    emit8 0xff >> x86_memindex_emit 6 basereg disp indexreg shift     ++x86_push_memindex :: Word8 -> Word32 -> Word8 -> Word8 -> CodeGen e s ()+x86_push_memindex basereg disp indexreg shft =+    emit8 0xff >> x86_memindex_emit 6 basereg disp indexreg shft++x86_push_imm_template :: CodeGen e s () x86_push_imm_template = x86_push_imm 0xf0f0f0f0++x86_push_imm :: Word32 -> CodeGen e s () x86_push_imm imm =         if x86_is_imm8 imm     then emit8 0x6A >> x86_imm_emit8 (fromIntegral imm)@@ -996,46 +1132,79 @@  -- POP instruction. +x86_pop_reg :: Word8 -> CodeGen e s () x86_pop_reg reg = emit8 (0x58 + reg)++x86_pop_mem :: Word32 -> CodeGen e s () x86_pop_mem mem = emit8 0x87 >> x86_mem_emit 0 mem    ++x86_pop_membase :: Word8 -> Word32 -> CodeGen e s () x86_pop_membase basereg disp =             emit8 0x87 >> x86_membase_emit 0 basereg disp      +x86_pushad :: CodeGen e s () x86_pushad = emit8 0x60++x86_pushfd :: CodeGen e s () x86_pushfd = emit8 0x9c++x86_popad :: CodeGen e s () x86_popad  = emit8 0x61++x86_popfd :: CodeGen e s () x86_popfd  = emit8 0x9d +x86_loop ::  Word8 -> CodeGen e s () x86_loop imm = emit8 0xe2 >> x86_imm_emit8 imm        ++x86_loope :: Word8 -> CodeGen e s () x86_loope imm = emit8 0xe1 >> x86_imm_emit8 imm       ++x86_loopne :: Word8 -> CodeGen e s () x86_loopne imm = emit8 0xe0 >> x86_imm_emit8 imm       +x86_jump32 :: Word32 -> CodeGen e s () x86_jump32 imm = emit8 0xe9 >> x86_imm_emit32 imm     ++x86_jump8 :: Word8 -> CodeGen e s () x86_jump8 imm = emit8 0xeb >> x86_imm_emit8 imm       ++x86_jump_reg :: Word8 -> CodeGen e s () x86_jump_reg reg = emit8 0xff >> x86_reg_emit 4 reg   ++x86_jump_mem :: Word32 -> CodeGen e s () x86_jump_mem mem = emit8 0xff >> x86_mem_emit 4 mem   ++x86_jump_membase :: Word8 -> Word32 -> CodeGen e s () x86_jump_membase basereg disp =            emit8 0xff >> x86_membase_emit 4 basereg disp       -- target is a pointer in our buffer. +{- x86_jump_code target =     do inst <- getCodeOffset        let t = target - inst - 2              if x86_is_imm8 t           then x86_jump8 (fromIntegral t)           else x86_jump32 (fromIntegral (t - 3))+-}+{- x86_jump_disp disp =       do let t = disp - 2        if x86_is_imm8 t           then x86_jump8 (fromIntegral t)           else x86_jump32 (t - 3)+-} +x86_branch8 :: Int -> Word8 -> Bool -> CodeGen e s () x86_branch8 cond imm is_signed =           do if is_signed              then emit8 (x86_cc_signed_map !! cond)           else emit8 (x86_cc_unsigned_map !! cond)            x86_imm_emit8 imm      ++x86_branch32 :: Int -> Word32 -> Bool -> CodeGen e s () x86_branch32 cond imm is_signed =          do emit8 0x0f             if is_signed   @@ -1043,21 +1212,25 @@           else emit8 ((x86_cc_unsigned_map !! cond) + 0x10)           x86_imm_emit32 imm      +x86_branch :: Int -> Int -> Bool -> CodeGen e s () x86_branch cond target is_signed =         do inst <- getCodeOffset        let offset = target - inst - 2;                if x86_is_imm8 offset           then x86_branch8 cond (fromIntegral offset) is_signed           else x86_branch32 cond (fromIntegral (offset - 4)) is_signed-+{- x86_branch_disp cond disp is_signed =      do let offset = disp - 2        if x86_is_imm8 offset           then x86_branch8 cond (fromIntegral offset) is_signed           else x86_branch32 cond (offset - 4) is_signed+-} +x86_jecxz :: Word8 -> CodeGen e s () x86_jecxz imm = emit8 0xe3 >> emit8 imm +x86_set_reg :: Int -> Word8 -> Bool -> CodeGen e s () x86_set_reg cond reg is_signed =           do emit8 0x0f             if is_signed@@ -1065,12 +1238,14 @@           else emit8 ((x86_cc_unsigned_map !! cond) + 0x20)           x86_reg_emit 0 reg      +x86_set_mem :: Int -> Word32 -> Bool -> CodeGen e s () x86_set_mem cond mem is_signed =           do emit8 0x0f             if is_signed           then emit8 ((x86_cc_signed_map !! cond) + 0x20)                else emit8 ((x86_cc_unsigned_map !! cond) + 0x20)           x86_mem_emit 0 mem     +x86_set_membase :: Int -> Word8 -> Word32 -> Bool -> CodeGen e s () x86_set_membase cond basereg disp is_signed =      do emit8 0x0f             if is_signed@@ -1117,18 +1292,21 @@     if imm == 0 then x86_ret else emit8 0xc2 >> x86_imm_emit16 imm      -- Conditional move instructions.-+x86_cmov ::Int -> Bool -> CodeGen e s () x86_cmov cond is_signed =     do emit8 0x0f             if is_signed           then emit8 ((x86_cc_signed_map !! cond) - 0x30)           else emit8 ((x86_cc_unsigned_map !! cond) - 0x30)+x86_cmov_reg :: Int -> Bool -> Word8 -> Word8 -> CodeGen e s () x86_cmov_reg cond is_signed dreg reg =             do x86_cmov cond is_signed        x86_reg_emit dreg reg  +x86_cmov_mem :: Int -> Bool -> Word8 -> Word32 -> CodeGen e s () x86_cmov_mem cond is_signed reg mem =      do x86_cmov cond is_signed        x86_mem_emit reg mem   +x86_cmov_membase :: Int -> Bool -> Word8 -> Word8 -> Word32 -> CodeGen e s () x86_cmov_membase cond is_signed reg basereg disp =         do x86_cmov cond is_signed        x86_membase_emit reg basereg disp      @@ -1163,6 +1341,7 @@  -- Fast instruction sequences for 1 to 7-byte noops. +x86_padding ::(Num t) => t -> CodeGen e s () x86_padding size =         case size of       1 -> x86_nop@@ -1221,341 +1400,273 @@        else return ()  -- TODO: Move signatures to definition, delete duplicates.-x86_cmpxchg_reg_reg ::-  forall e s.-  Word8-  -> Word8-  -> Harpy.CodeGenMonad.CodeGen e s ()-x86_cmpxchg_mem_reg ::-  forall e s.-  Word32-  -> Word8-  -> Harpy.CodeGenMonad.CodeGen e s ()-x86_cmpxchg_membase_reg ::-  forall e s.-  Word8-  -> Word32-  -> Word8-  -> Harpy.CodeGenMonad.CodeGen e s () x86_xchg_reg_reg ::-  forall a e s.   (Num a) =>   Word8   -> Word8   -> a-  -> Harpy.CodeGenMonad.CodeGen e s ()+  -> CodeGen e s () x86_xchg_mem_reg ::-  forall a e s.   (Num a) =>   Word32   -> Word8   -> a-  -> Harpy.CodeGenMonad.CodeGen e s ()+  -> CodeGen e s () x86_xchg_membase_reg ::-  forall a e s.   (Num a) =>   Word8   -> Word32   -> Word8   -> a-  -> Harpy.CodeGenMonad.CodeGen e s ()+  -> CodeGen e s () x86_xadd_reg_reg ::-  forall a e s.   (Num a) =>   Word8   -> Word8   -> a-  -> Harpy.CodeGenMonad.CodeGen e s ()+  -> CodeGen e s () x86_xadd_mem_reg ::-  forall a e s.   (Num a) =>   Word32   -> Word8   -> a-  -> Harpy.CodeGenMonad.CodeGen e s ()+  -> CodeGen e s () x86_xadd_membase_reg ::-  forall a e s.   (Num a) =>   Word8   -> Word32   -> Word8   -> a-  -> Harpy.CodeGenMonad.CodeGen e s ()+  -> CodeGen e s () x86_inc_mem ::-  forall e s. Word32 -> Harpy.CodeGenMonad.CodeGen e s ()+  Word32 -> CodeGen e s () x86_inc_membase ::-  forall e s.   Word8   -> Word32-  -> Harpy.CodeGenMonad.CodeGen e s ()+  -> CodeGen e s () x86_inc_reg ::-  forall e s. Word8 -> Harpy.CodeGenMonad.CodeGen e s ()+  Word8 -> CodeGen e s () x86_dec_mem ::-  forall e s. Word32 -> Harpy.CodeGenMonad.CodeGen e s ()+  Word32 -> CodeGen e s () x86_dec_membase ::-  forall e s.   Word8   -> Word32-  -> Harpy.CodeGenMonad.CodeGen e s ()+  -> CodeGen e s () x86_dec_reg ::-  forall e s. Word8 -> Harpy.CodeGenMonad.CodeGen e s ()+  Word8 -> CodeGen e s () x86_not_mem ::-  forall e s. Word32 -> Harpy.CodeGenMonad.CodeGen e s ()+  Word32 -> CodeGen e s () x86_not_membase ::-  forall e s.   Word8   -> Word32-  -> Harpy.CodeGenMonad.CodeGen e s ()+  -> CodeGen e s () x86_not_reg ::-  forall e s. Word8 -> Harpy.CodeGenMonad.CodeGen e s ()+  Word8 -> CodeGen e s () x86_neg_mem ::-  forall e s. Word32 -> Harpy.CodeGenMonad.CodeGen e s ()+  Word32 -> CodeGen e s () x86_neg_membase ::-  forall e s.   Word8   -> Word32-  -> Harpy.CodeGenMonad.CodeGen e s ()+  -> CodeGen e s () x86_neg_reg ::-  forall e s. Word8 -> Harpy.CodeGenMonad.CodeGen e s ()+  Word8 -> CodeGen e s () x86_alu_mem_imm ::-  forall e s.   Word8   -> Word32   -> Word32-  -> Harpy.CodeGenMonad.CodeGen e s ()+  -> CodeGen e s () x86_alu_membase_imm ::-  forall e s.   Word8   -> Word8   -> Word32   -> Word32-  -> Harpy.CodeGenMonad.CodeGen e s ()+  -> CodeGen e s () x86_alu_membase8_imm ::-  forall e s.   Word8   -> Word8   -> Word32   -> Word8-  -> Harpy.CodeGenMonad.CodeGen e s ()+  -> CodeGen e s () x86_alu_mem_reg ::-  forall e s.   Word8   -> Word32   -> Word8-  -> Harpy.CodeGenMonad.CodeGen e s ()+  -> CodeGen e s () x86_alu_membase_reg ::-  forall e s.   Word8   -> Word8   -> Word32   -> Word8-  -> Harpy.CodeGenMonad.CodeGen e s ()+  -> CodeGen e s () x86_alu_reg_reg ::-  forall e s.   Word8   -> Word8   -> Word8-  -> Harpy.CodeGenMonad.CodeGen e s ()+  -> CodeGen e s () x86_alu_reg8_reg8 ::-  forall e s.   Word8   -> Word8   -> Word8   -> Bool   -> Bool-  -> Harpy.CodeGenMonad.CodeGen e s ()+  -> CodeGen e s () x86_alu_reg_mem ::-  forall e s.   Word8   -> Word8   -> Word32-  -> Harpy.CodeGenMonad.CodeGen e s ()+  -> CodeGen e s () x86_alu_reg_membase ::-  forall e s.   Word8   -> Word8   -> Word8   -> Word32-  -> Harpy.CodeGenMonad.CodeGen e s ()+  -> CodeGen e s () x86_test_reg_imm ::-  forall e s.   Word8   -> Word32-  -> Harpy.CodeGenMonad.CodeGen e s ()+  -> CodeGen e s () x86_test_mem_imm ::-  forall e s.   Word32   -> Word32-  -> Harpy.CodeGenMonad.CodeGen e s ()+  -> CodeGen e s () x86_test_membase_imm ::-  forall e s.   Word8   -> Word32   -> Word32-  -> Harpy.CodeGenMonad.CodeGen e s ()+  -> CodeGen e s () x86_test_reg_reg ::-  forall e s.   Word8   -> Word8-  -> Harpy.CodeGenMonad.CodeGen e s ()+  -> CodeGen e s () x86_test_mem_reg ::-  forall e s.   Word32   -> Word8-  -> Harpy.CodeGenMonad.CodeGen e s ()+  -> CodeGen e s () x86_test_membase_reg ::-  forall e s.   Word8   -> Word32   -> Word8-  -> Harpy.CodeGenMonad.CodeGen e s ()+  -> CodeGen e s () x86_shift_reg_imm ::-  forall e s.   Word8   -> Word8   -> Word8-  -> Harpy.CodeGenMonad.CodeGen e s ()+  -> CodeGen e s () x86_shift_mem_imm ::-  forall e s.   Word8   -> Word32   -> Word8-  -> Harpy.CodeGenMonad.CodeGen e s ()+  -> CodeGen e s () x86_shift_membase_imm ::-  forall e s.   Word8   -> Word8   -> Word32   -> Word8-  -> Harpy.CodeGenMonad.CodeGen e s ()+  -> CodeGen e s () x86_shift_reg ::-  forall e s.   Word8   -> Word8-  -> Harpy.CodeGenMonad.CodeGen e s ()+  -> CodeGen e s () x86_shift_mem ::-  forall e s.   Word8   -> Word32-  -> Harpy.CodeGenMonad.CodeGen e s ()+  -> CodeGen e s () x86_shift_membase ::-  forall e s.   Word8   -> Word8   -> Word32-  -> Harpy.CodeGenMonad.CodeGen e s ()+  -> CodeGen e s () x86_shrd_reg ::-  forall e s.   Word8   -> Word8-  -> Harpy.CodeGenMonad.CodeGen e s ()+  -> CodeGen e s () x86_shrd_reg_imm ::-  forall e s.   Word8   -> Word8   -> Word8-  -> Harpy.CodeGenMonad.CodeGen e s ()+  -> CodeGen e s () x86_shld_reg ::-  forall e s.   Word8   -> Word8-  -> Harpy.CodeGenMonad.CodeGen e s ()+  -> CodeGen e s () x86_shld_reg_imm ::-  forall e s.   Word8   -> Word8   -> Word8-  -> Harpy.CodeGenMonad.CodeGen e s ()+  -> CodeGen e s () x86_mul_reg ::-  forall e s.-  Word8 -> Bool -> Harpy.CodeGenMonad.CodeGen e s ()+  Word8 -> Bool -> CodeGen e s () x86_mul_mem ::-  forall e s.-  Word32 -> Bool -> Harpy.CodeGenMonad.CodeGen e s ()+  Word32 -> Bool -> CodeGen e s () x86_mul_membase ::-  forall e s.   Word8   -> Word32   -> Bool-  -> Harpy.CodeGenMonad.CodeGen e s ()+  -> CodeGen e s () x86_imul_reg_reg ::-  forall e s.   Word8   -> Word8-  -> Harpy.CodeGenMonad.CodeGen e s ()+  -> CodeGen e s () x86_imul_reg_mem ::-  forall e s.   Word8   -> Word32-  -> Harpy.CodeGenMonad.CodeGen e s ()+  -> CodeGen e s () x86_imul_reg_membase ::-  forall e s.   Word8   -> Word8   -> Word32-  -> Harpy.CodeGenMonad.CodeGen e s ()+  -> CodeGen e s () x86_imul_reg_reg_imm ::-  forall e s.   Word8   -> Word8   -> Word32-  -> Harpy.CodeGenMonad.CodeGen e s ()+  -> CodeGen e s () x86_imul_reg_mem_imm ::-  forall e s.   Word8   -> Word32   -> Word32-  -> Harpy.CodeGenMonad.CodeGen e s ()+  -> CodeGen e s () x86_imul_reg_membase_imm ::-  forall e s.   Word8   -> Word8   -> Word32   -> Word32-  -> Harpy.CodeGenMonad.CodeGen e s ()+  -> CodeGen e s () x86_div_reg ::-  forall e s.-  Word8 -> Bool -> Harpy.CodeGenMonad.CodeGen e s ()+  Word8 -> Bool -> CodeGen e s () x86_div_mem ::-  forall e s.-  Word32 -> Bool -> Harpy.CodeGenMonad.CodeGen e s ()+  Word32 -> Bool -> CodeGen e s () x86_div_membase ::-  forall e s.   Word8   -> Word32   -> Bool-  -> Harpy.CodeGenMonad.CodeGen e s ()+  -> CodeGen e s () x86_mov_mem_reg ::-  forall t e s.   (Num t) =>   Word32   -> Word8   -> t-  -> Harpy.CodeGenMonad.CodeGen e s ()+  -> CodeGen e s () x86_mov_regp_reg ::-  forall t e s.   (Num t) =>   Word8   -> Word8   -> t-  -> Harpy.CodeGenMonad.CodeGen e s ()+  -> CodeGen e s () x86_mov_reg_regp ::-  forall t e s.   (Num t) =>   Word8   -> Word8   -> t-  -> Harpy.CodeGenMonad.CodeGen e s ()+  -> CodeGen e s () x86_mov_membase_reg ::-  forall t e s.   (Num t) =>   Word8   -> Word32   -> Word8   -> t-  -> Harpy.CodeGenMonad.CodeGen e s ()+  -> CodeGen e s () x86_mov_memindex_reg ::-  forall t e s.   (Num t) =>   Word8   -> Word32@@ -1563,31 +1674,27 @@   -> Word8   -> Word8   -> t-  -> Harpy.CodeGenMonad.CodeGen e s ()+  -> CodeGen e s () x86_mov_reg_reg ::-  forall t e s.   (Num t) =>   Word8   -> Word8   -> t-  -> Harpy.CodeGenMonad.CodeGen e s ()+  -> CodeGen e s () x86_mov_reg_mem ::-  forall t e s.   (Num t) =>   Word8   -> Word32   -> t-  -> Harpy.CodeGenMonad.CodeGen e s ()+  -> CodeGen e s () x86_mov_reg_membase ::-  forall t e s.   (Num t) =>   Word8   -> Word8   -> Word32   -> t-  -> Harpy.CodeGenMonad.CodeGen e s ()+  -> CodeGen e s () x86_mov_reg_memindex ::-  forall e s t.   (Num t) =>   Word8   -> Word8@@ -1595,29 +1702,25 @@   -> Word8   -> Word8   -> t-  -> Harpy.CodeGenMonad.CodeGen e s ()+  -> CodeGen e s () x86_mov_reg_imm ::-  forall e s.   Word8   -> Word32-  -> Harpy.CodeGenMonad.CodeGen e s ()+  -> CodeGen e s () x86_mov_mem_imm ::-  forall a e s.   (Num a) =>   Word32   -> Word32   -> a-  -> Harpy.CodeGenMonad.CodeGen e s ()+  -> CodeGen e s () x86_mov_membase_imm ::-  forall a e s.   (Num a) =>   Word8   -> Word32   -> Word32   -> a-  -> Harpy.CodeGenMonad.CodeGen e s ()+  -> CodeGen e s () x86_mov_memindex_imm ::-  forall a e s.   (Num a) =>   Word8   -> Word32@@ -1625,156 +1728,285 @@   -> Word8   -> Word32   -> a-  -> Harpy.CodeGenMonad.CodeGen e s ()-x86_lea_mem ::-  forall e s.-  Word8-  -> Word32-  -> Harpy.CodeGenMonad.CodeGen e s ()-x86_lea_membase ::-  forall e s.-  Word8-  -> Word8-  -> Word32-  -> Harpy.CodeGenMonad.CodeGen e s ()-x86_lea_memindex ::-  forall e s.-  Word8-  -> Word8-  -> Word32-  -> Word8-  -> Word8-  -> Harpy.CodeGenMonad.CodeGen e s ()-x86_widen_reg ::-  forall e s.-  Word8-  -> Word8-  -> Bool-  -> Bool-  -> Harpy.CodeGenMonad.CodeGen e s ()-x86_widen_mem ::-  forall e s.-  Word8-  -> Word32-  -> Bool-  -> Bool-  -> Harpy.CodeGenMonad.CodeGen e s ()-x86_widen_membase ::-  forall e s.-  Word8-  -> Word8-  -> Word32-  -> Bool-  -> Bool-  -> Harpy.CodeGenMonad.CodeGen e s ()-x86_widen_memindex ::-  forall e s.-  Word8-  -> Word8-  -> Word32-  -> Word8-  -> Word8-  -> Bool-  -> Bool-  -> Harpy.CodeGenMonad.CodeGen e s ()-x86_push_reg ::-  forall e s. Word8 -> Harpy.CodeGenMonad.CodeGen e s ()-x86_push_regp ::-  forall e s. Word8 -> Harpy.CodeGenMonad.CodeGen e s ()-x86_push_mem ::-  forall e s. Word32 -> Harpy.CodeGenMonad.CodeGen e s ()-x86_push_membase ::-  forall e s.-  Word8-  -> Word32-  -> Harpy.CodeGenMonad.CodeGen e s ()-x86_push_memindex ::-  forall e s.-  Word8-  -> Word32-  -> Word8-  -> Word8-  -> Harpy.CodeGenMonad.CodeGen e s ()-x86_push_imm_template ::-  forall e s. Harpy.CodeGenMonad.CodeGen e s ()-x86_push_imm ::-  forall e s. Word32 -> Harpy.CodeGenMonad.CodeGen e s ()-x86_pop_reg ::-  forall e s. Word8 -> Harpy.CodeGenMonad.CodeGen e s ()-x86_pop_mem ::-  forall e s. Word32 -> Harpy.CodeGenMonad.CodeGen e s ()-x86_pop_membase ::-  forall e s.-  Word8-  -> Word32-  -> Harpy.CodeGenMonad.CodeGen e s ()-x86_pushad :: forall e s. Harpy.CodeGenMonad.CodeGen e s ()-x86_pushfd :: forall e s. Harpy.CodeGenMonad.CodeGen e s ()-x86_popad :: forall e s. Harpy.CodeGenMonad.CodeGen e s ()-x86_popfd :: forall e s. Harpy.CodeGenMonad.CodeGen e s ()-x86_loop ::-  forall e s. Word8 -> Harpy.CodeGenMonad.CodeGen e s ()-x86_loope ::-  forall e s. Word8 -> Harpy.CodeGenMonad.CodeGen e s ()-x86_loopne ::-  forall e s. Word8 -> Harpy.CodeGenMonad.CodeGen e s ()-x86_jump32 ::-  forall e s. Word32 -> Harpy.CodeGenMonad.CodeGen e s ()-x86_jump8 ::-  forall e s. Word8 -> Harpy.CodeGenMonad.CodeGen e s ()-x86_jump_reg ::-  forall e s. Word8 -> Harpy.CodeGenMonad.CodeGen e s ()-x86_jump_mem ::-  forall e s. Word32 -> Harpy.CodeGenMonad.CodeGen e s ()-x86_jump_membase ::-  forall e s.-  Word8-  -> Word32-  -> Harpy.CodeGenMonad.CodeGen e s ()-x86_branch8 ::-  forall e s.-  Int -> Word8 -> Bool -> Harpy.CodeGenMonad.CodeGen e s ()-x86_branch32 ::-  forall e s.-  Int -> Word32 -> Bool -> Harpy.CodeGenMonad.CodeGen e s ()-x86_branch ::-  forall e s. Int -> Int -> Bool -> Harpy.CodeGenMonad.CodeGen e s ()-x86_jecxz ::-  forall e s. Word8 -> Harpy.CodeGenMonad.CodeGen e s ()-x86_set_reg ::-  forall e s.-  Int -> Word8 -> Bool -> Harpy.CodeGenMonad.CodeGen e s ()-x86_set_mem ::-  forall e s.-  Int -> Word32 -> Bool -> Harpy.CodeGenMonad.CodeGen e s ()-x86_set_membase ::-  forall e s.-  Int-  -> Word8-  -> Word32-  -> Bool-  -> Harpy.CodeGenMonad.CodeGen e s ()-x86_cmov_reg ::-  forall e s.-  Int-  -> Bool-  -> Word8-  -> Word8-  -> Harpy.CodeGenMonad.CodeGen e s ()-x86_cmov_mem ::-  forall e s.-  Int-  -> Bool-  -> Word8-  -> Word32-  -> Harpy.CodeGenMonad.CodeGen e s ()-x86_cmov_membase ::-  forall e s.-  Int-  -> Bool-  -> Word8-  -> Word8-  -> Word32-  -> Harpy.CodeGenMonad.CodeGen e s ()+  -> CodeGen e s () +-- SSE instructions.++data X86_SSE_PFX = X86_SSE_SD+                 | X86_SSE_SS+                 | X86_SSE_PD+                 | X86_SSE_PS+--newtype X86_SSE_PFX = X86_SSE_PFX (forall e s. CodeGen e s ())++x86_sse_sd, x86_sse_ss, x86_sse_pd, x86_sse_ps :: X86_SSE_PFX+x86_sse_sd = X86_SSE_SD+x86_sse_ss = X86_SSE_SS+x86_sse_pd = X86_SSE_PD+x86_sse_ps = X86_SSE_PS++emit_sse :: X86_SSE_PFX -> CodeGen e s ()+emit_sse X86_SSE_SD = emit8 0xf2+emit_sse X86_SSE_SS = emit8 0xf3+emit_sse X86_SSE_PD = emit8 0x66+emit_sse X86_SSE_PS = return ()++x86_sqrt_sse_reg_reg :: X86_SSE_PFX -> Word8 -> Word8 -> CodeGen e s ()+x86_sqrt_sse_reg_reg pfx dreg reg =+    do emit_sse pfx+       emit8 0x0f+       emit8 0x51+       x86_reg_emit dreg reg++x86_sqrt_sse_reg_mem :: X86_SSE_PFX -> Word8 -> Word32 -> CodeGen e s ()+x86_sqrt_sse_reg_mem pfx dreg mem =+    do emit_sse pfx+       emit8 0x0f+       emit8 0x51+       x86_mem_emit dreg mem++x86_sqrt_sse_reg_membase :: X86_SSE_PFX -> Word8 -> Word8 -> Word32 -> CodeGen e s ()+x86_sqrt_sse_reg_membase pfx dreg basereg disp =+    do emit_sse pfx+       emit8 0x0f+       emit8 0x51+       x86_membase_emit dreg basereg disp++x86_add_sse_reg_reg :: X86_SSE_PFX -> Word8 -> Word8 -> CodeGen e s ()+x86_add_sse_reg_reg pfx dreg reg =+    do emit_sse pfx+       emit8 0x0f+       emit8 0x58+       x86_reg_emit dreg reg++x86_add_sse_reg_mem :: X86_SSE_PFX -> Word8 -> Word32 -> CodeGen e s ()+x86_add_sse_reg_mem pfx dreg mem =+    do emit_sse pfx+       emit8 0x0f+       emit8 0x58+       x86_mem_emit dreg mem++x86_add_sse_reg_membase :: X86_SSE_PFX -> Word8 -> Word8 -> Word32 -> CodeGen e s ()+x86_add_sse_reg_membase pfx dreg basereg disp =+    do emit_sse pfx+       emit8 0x0f+       emit8 0x58+       x86_membase_emit dreg basereg disp++x86_mul_sse_reg_reg :: X86_SSE_PFX -> Word8 -> Word8 -> CodeGen e s ()+x86_mul_sse_reg_reg pfx dreg reg =+    do emit_sse pfx+       emit8 0x0f+       emit8 0x59+       x86_reg_emit dreg reg++x86_mul_sse_reg_mem :: X86_SSE_PFX -> Word8 -> Word32 -> CodeGen e s ()+x86_mul_sse_reg_mem pfx dreg mem =+    do emit_sse pfx+       emit8 0x0f+       emit8 0x59+       x86_mem_emit dreg mem++x86_mul_sse_reg_membase :: X86_SSE_PFX -> Word8 -> Word8 -> Word32 -> CodeGen e s ()+x86_mul_sse_reg_membase pfx dreg basereg disp =+    do emit_sse pfx+       emit8 0x0f+       emit8 0x59+       x86_membase_emit dreg basereg disp++x86_sub_sse_reg_reg :: X86_SSE_PFX -> Word8 -> Word8 -> CodeGen e s ()+x86_sub_sse_reg_reg pfx dreg reg =+    do emit_sse pfx+       emit8 0x0f+       emit8 0x5c+       x86_reg_emit dreg reg++x86_sub_sse_reg_mem :: X86_SSE_PFX -> Word8 -> Word32 -> CodeGen e s ()+x86_sub_sse_reg_mem pfx dreg mem =+    do emit_sse pfx+       emit8 0x0f+       emit8 0x5c+       x86_mem_emit dreg mem++x86_sub_sse_reg_membase :: X86_SSE_PFX -> Word8 -> Word8 -> Word32 -> CodeGen e s ()+x86_sub_sse_reg_membase pfx dreg basereg disp =+    do emit_sse pfx+       emit8 0x0f+       emit8 0x5c+       x86_membase_emit dreg basereg disp++x86_min_sse_reg_reg :: X86_SSE_PFX -> Word8 -> Word8 -> CodeGen e s ()+x86_min_sse_reg_reg pfx dreg reg =+    do emit_sse pfx+       emit8 0x0f+       emit8 0x5d+       x86_reg_emit dreg reg++x86_min_sse_reg_mem :: X86_SSE_PFX -> Word8 -> Word32 -> CodeGen e s ()+x86_min_sse_reg_mem pfx dreg mem =+    do emit_sse pfx+       emit8 0x0f+       emit8 0x5d+       x86_mem_emit dreg mem++x86_min_sse_reg_membase :: X86_SSE_PFX -> Word8 -> Word8 -> Word32 -> CodeGen e s ()+x86_min_sse_reg_membase pfx dreg basereg disp =+    do emit_sse pfx+       emit8 0x0f+       emit8 0x5d+       x86_membase_emit dreg basereg disp++x86_div_sse_reg_reg :: X86_SSE_PFX -> Word8 -> Word8 -> CodeGen e s ()+x86_div_sse_reg_reg pfx dreg reg =+    do emit_sse pfx+       emit8 0x0f+       emit8 0x5e+       x86_reg_emit dreg reg++x86_div_sse_reg_mem :: X86_SSE_PFX -> Word8 -> Word32 -> CodeGen e s ()+x86_div_sse_reg_mem pfx dreg mem =+    do emit_sse pfx+       emit8 0x0f+       emit8 0x5e+       x86_mem_emit dreg mem++x86_div_sse_reg_membase :: X86_SSE_PFX -> Word8 -> Word8 -> Word32 -> CodeGen e s ()+x86_div_sse_reg_membase pfx dreg basereg disp =+    do emit_sse pfx+       emit8 0x0f+       emit8 0x5e+       x86_membase_emit dreg basereg disp++x86_max_sse_reg_reg :: X86_SSE_PFX -> Word8 -> Word8 -> CodeGen e s ()+x86_max_sse_reg_reg pfx dreg reg =+    do emit_sse pfx+       emit8 0x0f+       emit8 0x5f+       x86_reg_emit dreg reg++x86_max_sse_reg_mem :: X86_SSE_PFX -> Word8 -> Word32 -> CodeGen e s ()+x86_max_sse_reg_mem pfx dreg mem =+    do emit_sse pfx+       emit8 0x0f+       emit8 0x5f+       x86_mem_emit dreg mem++x86_max_sse_reg_membase :: X86_SSE_PFX -> Word8 -> Word8 -> Word32 -> CodeGen e s ()+x86_max_sse_reg_membase pfx dreg basereg disp =+    do emit_sse pfx+       emit8 0x0f+       emit8 0x5f+       x86_membase_emit dreg basereg disp++x86_mov_sse_reg_reg :: X86_SSE_PFX -> Word8 -> Word8 -> CodeGen e s ()+x86_mov_sse_reg_reg pfx dreg reg =+    do emit_sse pfx+       emit8 0x0f+       emit8 0x10+       x86_reg_emit dreg reg++x86_mov_sse_reg_mem :: X86_SSE_PFX -> Word8 -> Word32 -> CodeGen e s ()+x86_mov_sse_reg_mem pfx dreg mem =+    do emit_sse pfx+       emit8 0x0f+       emit8 0x10+       x86_mem_emit dreg mem++x86_mov_sse_reg_membase :: X86_SSE_PFX -> Word8 -> Word8 -> Word32 -> CodeGen e s ()+x86_mov_sse_reg_membase pfx dreg basereg disp =+    do emit_sse pfx+       emit8 0x0f+       emit8 0x10+       x86_membase_emit dreg basereg disp++x86_mov_sse_mem_reg :: X86_SSE_PFX -> Word32 -> Word8 -> CodeGen e s ()+x86_mov_sse_mem_reg pfx mem reg =+    do emit_sse pfx+       emit8 0x0f+       emit8 0x11+       x86_mem_emit reg mem++x86_mov_sse_membase_reg :: X86_SSE_PFX -> Word8 -> Word32 -> Word8 -> CodeGen e s ()+x86_mov_sse_membase_reg pfx basereg disp reg =+    do emit_sse pfx+       emit8 0x0f+       emit8 0x11+       x86_membase_emit reg basereg disp++x86_ucomisd_reg_reg :: Word8 -> Word8 -> CodeGen e s ()+x86_ucomisd_reg_reg dreg reg =+    do emit8 0x66+       emit8 0x0f+       emit8 0x2e+       x86_reg_emit dreg reg++x86_ucomisd_reg_mem :: Word8 -> Word32 -> CodeGen e s ()+x86_ucomisd_reg_mem dreg mem =+    do emit8 0x66+       emit8 0x0f+       emit8 0x2e+       x86_mem_emit dreg mem++x86_ucomisd_reg_membase :: Word8 -> Word8 -> Word32 -> CodeGen e s ()+x86_ucomisd_reg_membase dreg basereg disp =+    do emit8 0x66+       emit8 0x0f+       emit8 0x2e+       x86_membase_emit dreg basereg disp++x86_ucomiss_reg_reg :: Word8 -> Word8 -> CodeGen e s ()+x86_ucomiss_reg_reg dreg reg =+    do emit8 0x0f+       emit8 0x2e+       x86_reg_emit dreg reg++x86_ucomiss_reg_mem :: Word8 -> Word32 -> CodeGen e s ()+x86_ucomiss_reg_mem dreg mem =+    do emit8 0x0f+       emit8 0x2e+       x86_mem_emit dreg mem++x86_ucomiss_reg_membase :: Word8 -> Word8 -> Word32 -> CodeGen e s ()+x86_ucomiss_reg_membase dreg basereg disp =+    do emit8 0x0f+       emit8 0x2e+       x86_membase_emit dreg basereg disp++x86_comisd_reg_reg :: Word8 -> Word8 -> CodeGen e s ()+x86_comisd_reg_reg dreg reg =+    do emit8 0x66+       emit8 0x0f+       emit8 0x2f+       x86_reg_emit dreg reg++x86_comisd_reg_mem :: Word8 -> Word32 -> CodeGen e s ()+x86_comisd_reg_mem dreg mem =+    do emit8 0x66+       emit8 0x0f+       emit8 0x2f+       x86_mem_emit dreg mem++x86_comisd_reg_membase :: Word8 -> Word8 -> Word32 -> CodeGen e s ()+x86_comisd_reg_membase dreg basereg disp =+    do emit8 0x66+       emit8 0x0f+       emit8 0x2e+       x86_membase_emit dreg basereg disp++x86_comiss_reg_reg :: Word8 -> Word8 -> CodeGen e s ()+x86_comiss_reg_reg dreg reg =+    do emit8 0x0f+       emit8 0x2f+       x86_reg_emit dreg reg++x86_comiss_reg_mem :: Word8 -> Word32 -> CodeGen e s ()+x86_comiss_reg_mem dreg mem =+    do emit8 0x0f+       emit8 0x2f+       x86_mem_emit dreg mem++x86_comiss_reg_membase :: Word8 -> Word8 -> Word32 -> CodeGen e s ()+x86_comiss_reg_membase dreg basereg disp =+    do emit8 0x0f+       emit8 0x2e+       x86_membase_emit dreg basereg disp 
Harpy/X86Disassembler.hs view
@@ -1,6 +1,6 @@ -------------------------------------------------------------------------- -- |--- Module      :  X86Disassembler+-- Module      :  Harpy.X86Disassembler -- Copyright   :  (c) Martin Grabmueller and Dirk Kleeblatt -- License     :  GPL -- @@ -10,9 +10,9 @@ -- -- Disassembler for x86 machine code. ----- This is a disassembler for object code for the x86 architecture.  It--- provides functions for disassembling byte arrays, byte lists and files--- containing raw binary code.+-- This is a disassembler for object code for the x86 architecture.+-- It provides functions for disassembling byte arrays, byte lists and+-- memory blocks containing raw binary code. --  -- Features: --@@ -67,8 +67,7 @@   disassembleList,   disassembleArray,   showIntel,-  showAtt,-  testFile+  showAtt   ) where  import Text.ParserCombinators.Parsec@@ -501,15 +500,21 @@ -- | All operands are in one of the following locations: -- -- - Constants in the instruction stream+-- -- - Memory locations+-- -- - Registers -- -- Memory locations are referred to by on of several addressing modes: -- -- - Absolute (address in instruction stream)+-- -- - Register-indirect (address in register)+-- -- - Register-indirect with displacement+-- -- - Base-Index with scale+-- -- - Base-Index with scale and displacement  -- -- Displacements can be encoded as 8 or 32-bit immediates in the@@ -583,15 +588,15 @@ -- | Some opcodes can operate on data of several widths.  This information -- is encoded in instructions using the following enumeration type.. -data InstrOperandSize = OPNONE 	-- ^ No operand size specified-       	        | OP8 		-- ^ 8-bit integer operand-       	        | OP16 		-- ^ 16-bit integer operand-       	        | OP32		-- ^ 32-bit integer operand-       	        | OP64		-- ^ 64-bit integer operand-       	        | OP128		-- ^ 128-bit integer operand-       	        | OPF32	    -- ^ 32-bit floating point operand-       	        | OPF64	    -- ^ 64-bit floating point operand-       	        | OPF80	    -- ^ 80-bit floating point operand+data InstrOperandSize = OPNONE -- ^ No operand size specified+       	        | OP8 	       -- ^ 8-bit integer operand+       	        | OP16 	       -- ^ 16-bit integer operand+       	        | OP32	       -- ^ 32-bit integer operand+       	        | OP64	       -- ^ 64-bit integer operand+       	        | OP128	       -- ^ 128-bit integer operand+       	        | OPF32	       -- ^ 32-bit floating point operand+       	        | OPF64	       -- ^ 64-bit floating point operand+       	        | OPF80	       -- ^ 80-bit floating point operand   deriving (Show)  @@ -602,13 +607,14 @@ -- the instruction.  data Instruction = -    BadInstruction Word8 String Int [Word8] -- ^ Invalid instruction-  | Instruction { opcode :: Opcode, 	-- ^ Opcode of the instruction+    BadInstruction Word8 String Int [Word8]   -- ^ Invalid instruction+  | PseudoInstruction Int String                  -- ^ Pseudo instruction, e.g. label+  | Instruction { opcode :: Opcode, 	      -- ^ Opcode of the instruction        		  opsize :: InstrOperandSize, -- ^ Operand size, if any-       		  operands :: [Operand], -- ^ Instruction operands-                  address :: Int,    -- ^ Start address of instruction-       		  bytes ::[Word8]	-- ^ Instruction bytes-                 }			-- ^ Valid instruction+       		  operands :: [Operand],      -- ^ Instruction operands+                  address :: Int,             -- ^ Start address of instruction+       		  bytes ::[Word8]	      -- ^ Instruction bytes+                 }			      -- ^ Valid instruction  instance Show Instruction where     show = showIntel@@ -620,7 +626,9 @@  hex32 :: Int -> String hex32 i =-    let s = showHex i ""+    let w :: Word32+        w = fromIntegral i+        s = showHex w ""     in take (8 - length s) (repeat '0') ++ s  -- Show a byte as an 2-digit hexadecimal number with leading zeroes.@@ -637,17 +645,24 @@ -- Intel style: -- -- - Destination operand comes first, source second.+-- -- - No register or immediate prefixes.+-- -- - Memory operands are annotated with operand size.--- - Hexadecimal numbers are suffixed with H and prefixed with 0 if+--+-- - Hexadecimal numbers are suffixed with @H@ and prefixed with @0@ if --   necessary. -- -- AT&T style: -- -- - Source operand comes first, destination second.--- - Register names are prefixes with %.--- - Immediates are prefixed with $.--- - Hexadecimal numbers are prefixes with 0x+--+-- - Register names are prefixes with @%@.+--+-- - Immediates are prefixed with @$@.+--+-- - Hexadecimal numbers are prefixes with @0x@+-- -- - Opcodes are suffixed with operand size, when ambiguous otherwise. data ShowStyle = IntelStyle		-- ^ Show in Intel style                 | AttStyle		-- ^ Show in AT&T style@@ -658,6 +673,8 @@ showIntel (BadInstruction b desc pos bytes) =     showPosBytes pos bytes ++     "(" ++ desc ++ ", byte=" ++ show b ++ ")"+showIntel (PseudoInstruction pos s) =+    hex32 pos ++ "                          " ++ s showIntel (Instruction op opsize [] pos bytes) =      showPosBytes pos bytes ++        showOp op@@ -672,6 +689,8 @@ showAtt (BadInstruction b desc pos bytes) =      showPosBytes pos bytes ++        "(" ++ desc ++ ", byte=" ++ show b ++ ")"+showAtt (PseudoInstruction pos s) =+    hex32 pos ++ "                          " ++ s showAtt (Instruction op opsize [] pos bytes) =      showPosBytes pos bytes ++        showOp op ++ showInstrSuffix [] opsize@@ -731,13 +750,15 @@  -- Show an immediate value in hexadecimal. +showImm :: Word32 -> String showImm i =   "$0x" ++ showHex i "" +showIntelImm :: Word32 -> String showIntelImm i =   let h = showHex i "H"       (f:_) = h-  in (if isDigit f then "" else "0") ++ showHex i "H"+  in (if isDigit f then "" else "0") ++ h  -- Show an address in hexadecimal. @@ -750,7 +771,7 @@       w = fromIntegral i       h = showHex w "H"       (f:_) = h-  in (if isDigit f then "" else "0") ++ showHex w "H"+  in (if isDigit f then "" else "0") ++ h  -- | Disassemble a block of memory.  Starting at the location -- pointed to by the given pointer, the given number of bytes are
Makefile view
+ NEWS view
@@ -0,0 +1,46 @@+							-*-outline-*-+* Harpy NEWS++** New in version 0.4++- New convenience top-level module "Harpy", which re-exports+  Harpy.CodeGenMonad, Harpy.Call and Harpy.X86Assembler++- It is now possible to override Harpy's automatic code buffer+  management.  The new field 'customCodeBuffer' in the type+  'CodeGenConfig' can be set to 'Just (buf, size)', where 'buf' is a+  pointer to a memory region of 'size' bytes.  Harpy will then use the+  supplied code buffer and will not perform any automatic code buffer+  allocation on overflow.  Overflow checking is still performed and+  will result in an exception in the CodeGen monad.++- When using the high-level assembler in X86Assembler, the code buffer+  is automatically protected from overflow.++- Floating point operations added to X86Assembler (only for double+  operands yet).++- Preliminary support for SSE instructions.  Currently, only the+  packed and scalar floating-point arithmetic operations are supported+  (both in the low-level module Harpy.X86CodeGen and as methods in+  Harpy.X86Assembler)++- Code buffer default size has been increased from 128 to 4096 bytes.++- The CodeGenMonad fails when a label is defined twice.++- It is now possible to associate names with labels, using the new+  operation newNamedLabel.  The given names will show up in the+  disassembly, which makes debugging of generated code much easier.++- The doc directory contains a second, slightly larger tutorial now.++- The examples/evaluator directory contains a small example+  interpreter for arithmetic expressions, which translates expressions+  entered at the keayboard to machine code on the fly.  This is the+  demo program we presented at the Haskell Workshop 2007.++** New in version 0.2++- Everything is new!  This is the first released version.+
+ doc/Makefile view
@@ -0,0 +1,18 @@+all: larger-tutorial.pdf++larger-tutorial.pdf: larger-tutorial.tex ++larger-tutorial.tex: larger-tutorial.lhs+	lhs2TeX $< > $@++%.pdf: %.tex+	pdflatex $<+	pdflatex $<++clean:+	rm -f larger-tutorial.aux larger-tutorial.toc\+ larger-tutorial.tex larger-tutorial.log larger-tutorial.out\+ larger-tutorial.ptb++really-clean: clean+	rm -f larger-tutorial.pdf
+ doc/larger-tutorial.lhs view
@@ -0,0 +1,312 @@+\documentclass[a4paper,11pt]{article}++\usepackage[margin=2.5cm]{geometry}+\usepackage{hyperref}++%include polycode.fmt+%format alpha = "\alpha"+++\title{\textbf{Slightly Larger Harpy Tutorial}}+\author{Martin Grabmüller \and Dirk Kleeblatt}++\begin{document}+\maketitle+\begin{abstract}\noindent+This tutorial is an introduction to some of the more advanced features+of Harpy.  In the course of the tutorial, we will build a small+run-time compiler for a call-by-value lambda-calculus.+This document is written as a litarate Haskell program, so you can+compile and run it without any modifications.  +\end{abstract}++\section{Introduction}++In this tutorial, we develop a small run-time compiler for a simple+call-by-value lambda calculus extended with natural number constants.++Before reading, you should have read the Harpy tutorial, which+introduces the most basic concepts.  We also recommend to have a+running \verb|ghci| session running for loading the literate Haskell+script of this tutorial and to try it out.  Maybe you want to have the+Harpy API documentation available, too.++\section{The Code}++To make use of Harpy and (a subset of) the x86 assembler instructions, we need+to import some modules.++\begin{code}+import Harpy.CodeGenMonad+import Harpy.X86Assembler+import Harpy.X86Disassembler+import Foreign+import Control.Monad+import Control.Monad.Trans+import Data.List +\end{code}++The following module system hackery is necessary, because the+|Harpy.X86Assembler| module exports a method called+|div|, which clashes with the |div| function+exported by the Haskell Prelude.  The prelude |div| will be+hidden, but is still available as a qualified name.++\begin{code}+import Prelude hiding (div)+import qualified Prelude+\end{code}++\subsection{Data Types}++In the following, we define several data types for representing lambda+calculus terms++A |Name| represents a variable name.  In a real+implementation, it would probably be more complicated data type for+handling qualified or compiler-generated names.  For now, a string+will suffice.++\begin{code}+type Name = String+\end{code}++In our implementation, a variable may refer to (a) a global variable,+which is represented by its address, (b) a parameter, which is+represented by the number of enclosing lambda expression, or (c) a+free variable, which is represented by its index into the current code+closure.++\begin{code}+data VarLoc  =  Global Word32+	     |  Param Int+             |  Free Int+             deriving (Show)+\end{code}++A compile-time environment represents a mapping from variable names to+variable locations.++\begin{code}+data Env = Env [(Name, VarLoc)]+\end{code}++An expression is represented by the following data type and may be a+variable, an immediate value (integer constant), a lambda abstraction+or an application expression.++\begin{code}+data Exp  =  Var Name+	  |  Imm Int+          |  Abs Name Exp+          |  App Exp Exp+\end{code}++The |State| type represents the state of a running program.+It consists of a pointer to the next available word of heap memory,+and a pointer to the end of the heap.  These two values are necessary+for dynamically allocating memory and for performing heap-overflow+checks.++\begin{code}+data State = State {  heap     :: Ptr Word32,+		      heapEnd  :: Ptr Word32}+\end{code}++The following test expressions are constructed using the constructors of+type |Exp| and are to be evaluated by the main program.++\begin{code}+testExp0 = App (Abs "x" (Var "x")) (Imm 12)+testExp1 = App (App (Abs "x" (Abs "y" (Var "x"))) (Imm 12)) (Imm 23)+\end{code}++\subsection{Main Program}++Before presenting the compiler, we will have a look at how it is used.+The entry point to the dynamic compiler is the function+|interpret|, which takes an expression and returns the value+calculated by the expression.  The main program simply prints the+result.++\begin{code}+$(callDecl "callFunc" [t|Word32|])+\end{code}++\begin{code}+main :: IO ()+main = do  res <- interpret testExp1+           putStrLn $ "Result: " ++ show res+\end{code}++The |interpret| function allocates 16 kbytes of heap and+compiles the expression.  The |State| of the compiler is+passed to the |runCodeGen| function as a user state.++\begin{code}+interpret :: Exp -> IO Word32+interpret exp =+    do  let heapSize = 1024 * 16+        heap <- mallocBytes heapSize+        (_, Right res) <- runCodeGen (compileTop exp) (Env []) +	 		  (State heap (heap `plusPtr` +				       (heapSize `Prelude.div` 4)))+        return res+\end{code}++\subsection{Compilation}++The compilation starts in the function |compileTop|, which emits code+for creating a stack frame, saving all general-purpose registers+(except \verb|eax|, which will contain the result of the execution),+and finally compiles the expression.  Afterwards, all registers are+restored and the function is called.  In addition we call the+disassembler on the generated code and print it out.  This is a useful+debuggin aid when generating assembler code.++\begin{code}+compileTop :: Exp -> CodeGen Env State Word32+compileTop exp =+    do  st <- getState+        push ebp+        mov ebp esp+        push ebx+        push ecx+        push edi+        push esi+        mov ecx ((fromIntegral (ptrToWordPtr (heap st))) :: Word32)+        compile exp+        pop esi+        pop edi+        pop ecx+        pop ebx+        mov esp ebp+        pop ebp+        ret+        y <- callFunc+        dis <- disassemble+        liftIO $ mapM_ (putStrLn . showIntel) dis+        return y++\end{code}++\subsubsection{Handling Variables}++The |findVar| function looks up a variable in the+environment and returns its binding.++\begin{code}+findVar s = +    do  Env e <- getEnv+        case lookup s e of+          Just vl -> return vl+	  Nothing -> error ("unbound variable: " ++ s)+\end{code}++For the implementation of closures, we need to calculate free+variables of expressions, so that we know what to store into closures+and how to access free variables from the body of a lambda expression.++\begin{code}+freeVariables (Var s) = return [s]+freeVariables (Imm _) = return []+freeVariables (Abs x b) = liftM (delete x) (freeVariables b)+freeVariables (App e1 e2) = liftM2 union (freeVariables e1) (freeVariables e2)+\end{code}++\subsubsection{Heap Allocation}++Closures are the only dynamically allocated structures in our little+compiler.  They are allocated from a contiguous block of malloc'ed+memory, which is passed in the code generator monad's state.  The+following function generates code for allocating $w$ words of memory+in the heap, and returning a pointer to the memory in register+\verb|eax|.  On heap overflow, a breakpoint instruction is executed.++\begin{code}+emitAlloc w =+    do  mov eax ecx+        st <- getState+        cmp ecx (fromIntegral (ptrToWordPtr (heapEnd st)) :: Word32)+        next <- newLabel+        jl next+        breakpoint+        defineLabel next+        add ecx ((4 * w) :: Word32)+\end{code}++\subsubsection{The Compilation Proper}++Finally, the |compile| function compiles an expression.+Constants are simply loaded into the result register, values of+variables are retrieved from their respective addresses (global+variables from absolute addresses, parameters relative to the stack+base pointer, and free variables relative to the closure pointer.++\begin{code}+compile :: Exp -> CodeGen Env State ()+compile (Imm i) = +    do  mov eax (fromIntegral i :: Word32)+compile (Var s) =+    do  c <- findVar s+        case c of+          Global addr -> mov eax (Addr addr)+	  Param ofs -> mov eax (Disp (fromIntegral ofs), ebp)+	  Free ofs -> mov eax (Disp (fromIntegral ofs), esi)+\end{code}++Lambda expressions are more complicated.  We first need to calculate+the set of free variables of the body expression.  Then the body of+the expression is compiled (with a jump around its code, so that it is+not actually executed at this point).  Then a closure record is+allocated on the heap, a code pointer to the body is stored in the+first word, and the values of all free variables of the body are+calculated and moved into the remaining fields of the closure.++The result is a pointer to the new closure, returned in \verb|eax|, as+usual.++\begin{code}+compile exp@(Abs x body) =+    do  fv <- freeVariables exp+        let frees = zip fv (map Free [4,8..])+        next <- newLabel+        jmp next+        f <- setLabel+        push ebp+        mov ebp esp+        mov esi (Disp 8, ebp)+        withEnv (Env ((x, Param 12) : frees)) (compile body)+        mov esp ebp+        pop ebp+        ret+        defineLabel next+        emitAlloc (fromIntegral (length frees + 1))+        mov edi eax+        mov (Disp 0, edi) f+        if length frees > 0+           then do  push eax+                    mapM_ (\ (x, Free ofs) -> +                           do  compile (Var x)+                               mov (Disp (fromIntegral ofs), edi) eax)+                      frees+                    pop eax+           else return ()+compile (App e1 e2) = +    do  compile e2+        push eax+        compile e1+        push eax+        call (Disp 0, eax)+        add esp (8 :: Word32)+\end{code}++\section{Conclusion}++This completes our little just-in-time compiled lambda calculus+evaluator.  We hope that this tutorial makes clear many of the fine+points in using the libray.++Happy Harpy Hacking in Haskell!++\end{document}
+ examples/evaluator/ArithParser.hs view
@@ -0,0 +1,73 @@+module ArithParser where++import Control.Monad++import ArithTypes++import Foreign++import Text.ParserCombinators.Parsec+import qualified Text.ParserCombinators.Parsec.Token as P+import Text.ParserCombinators.Parsec.Language+import Text.ParserCombinators.Parsec.Expr++lexer :: P.TokenParser ()+lexer  = P.makeTokenParser +         (haskellStyle+         { reservedOpNames = ["*","/","+","-"]+         })++statement :: Parser Stmt+statement = do s <- statement'+               eof+               return s++statement' :: Parser Stmt+statement' = try((do [i] <- identifier+                     if i < 'a' || i > 'z'+                       then fail "character a-z expected"+                       else return ()+                     symbol ":="+                     e <- expr+                     return $ Assign i e) <?> "assignment")+            <|> liftM Cmd cmd+            <|> liftM Print expr++cmd :: Parser Cmd+cmd = try (do symbol ":help"+              return Help)+      <|> try (do symbol ":verbose"+                  return Verbose)+      <|> (do symbol ":quit"+              return Quit)++expr    :: Parser Exp+expr    = buildExpressionParser table factor+        <?> "expression"++table   = [[op "*" Mul AssocLeft, op "/" Div AssocLeft]+          ,[op "+" Add AssocLeft, op "-" Sub AssocLeft]+          ]+        where+          op s f assoc+             = Infix (do{ reservedOp s; return f} <?> "operator") assoc++factor  =   parens expr+        <|> liftM (Lit . fromInteger) natural+        <|> (do [i] <- identifier+                if i < 'a' || i > 'z'+                   then fail "character a-z expected"+                   else return ()+                return $ Var i)+        <?> "simple expression"++whiteSpace= P.whiteSpace lexer+lexeme    = P.lexeme lexer+symbol    = P.symbol lexer+natural   = P.natural lexer+parens    = P.parens lexer+semi      = P.semi lexer+identifier= P.identifier lexer+reserved  = P.reserved lexer+reservedOp= P.reservedOp lexer+
+ examples/evaluator/ArithTypes.hs view
@@ -0,0 +1,22 @@+module ArithTypes where++import Foreign++data Stmt = Assign Char Exp+          | Print Exp+          | Cmd Cmd+          deriving (Show)++data Cmd = Help+         | Quit+         | Verbose+         deriving (Show)++data Exp = Add Exp Exp+         | Sub Exp Exp+         | Mul Exp Exp+         | Div Exp Exp+         | Lit Int32+         | Var Char+         deriving (Show)+
+ examples/evaluator/Evaluator.hs view
@@ -0,0 +1,118 @@+module Main(main) where++import ArithTypes+import ArithParser++import Harpy+import Harpy.X86Disassembler++import Foreign++import Control.Monad++import System.Console.Readline++import Text.ParserCombinators.Parsec++$(callDecl "callAsWord32" [t|Word32|])++main :: IO ()+main = do putStrLn "\n\n\n\nHarpy Interpreter"+          putStrLn "(type :help to see a help message)"+          allocaArray 26 (\ p -> mapM_ (\ i -> poke (advancePtr p i) 0) [0..25] >> repl p False)++repl :: Ptr Int32 -> Bool -> IO ()+repl env verbose =+    do s <- readline "@ "+       case s of+         Nothing -> return ()+         Just s' -> do addHistory s'+                       interpret env verbose s'++interpret :: Ptr Int32 -> Bool -> String -> IO ()+interpret env verbose s = +    do let e = parse statement "<standard input>" s+       case e of+         Left err -> do putStrLn (show err)+                        repl env verbose+         Right stmt -> run env verbose stmt++run :: Ptr Int32 -> Bool -> Stmt -> IO ()+run env verbose (Cmd Help) = +    do putStrLn "Enter an arithmetic expression to evaluate it"+       putStrLn "  e.g. 5 / 2"+       putStrLn "Enter an assignment to set a variable"+       putStrLn "  e.g. a := 4 * 2 - (6 + 1)"+       putStrLn "Enter :help to see this message again"+       putStrLn "Enter :quit to exit"+       putStrLn "Enter :verbose to toggle disassembly output"+       repl env verbose++run env _ (Cmd Quit) = return ()++run env verbose (Cmd Verbose) = repl env (Prelude.not verbose)++run env verbose stmt@(Assign var exp) =+    do (i, ins) <- eval' env stmt+       when verbose (mapM_ (putStrLn . showIntel) ins)+       repl env verbose++run env verbose stmt@(Print exp) =+    do (i, ins) <- eval' env stmt+       putStrLn (show i)+       when verbose (mapM_ (putStrLn . showIntel) ins)+       repl env verbose++-- Function for compiling and executing statements.+eval' :: Ptr Int32 -> Stmt -> IO (Int32, [Instruction])+eval' env e = do (_, Right v) <- runCodeGen (compileAndRun e) env ()+                 return v++compileAndRun :: Stmt -> CodeGen (Ptr Int32) s (Int32, [Instruction])+compileAndRun (Assign c exp) = +    do entryCode+       compileExp exp+       env <- getEnv+       mov (variableAddress env c) eax+       exitCode+       d <- disassemble+       callAsVoid+       return (0, d)+compileAndRun (Print exp) =+    do entryCode+       compileExp exp+       exitCode+       d <- disassemble+       r <- callAsWord32+       return (fromIntegral r, d)++compileExp :: Exp -> CodeGen (Ptr Int32) s ()+compileExp (Add e1 e2) = compileBinOp e1 e2 (add eax (Ind esp))+compileExp (Sub e1 e2) = compileBinOp e1 e2 (sub eax (Ind esp))+compileExp (Mul e1 e2) = compileBinOp e1 e2 (imul InPlace eax (Ind esp))+compileExp (Div e1 e2) = compileBinOp e1 e2 (cdq >> idiv (Ind esp))+compileExp (Lit i) = mov eax ((fromIntegral i) :: Word32)+compileExp (Var c) = do env <- getEnv+                        mov eax (variableAddress env c)++compileBinOp :: Exp -> Exp -> CodeGen (Ptr Int32) s a -> CodeGen (Ptr Int32) s ()+compileBinOp e1 e2 op = do compileExp e2+                           push eax+                           compileExp e1+                           op+                           add esp (4 :: Word32) ++entryCode :: CodeGen e s ()+entryCode = do push ebp+               mov ebp esp++exitCode :: CodeGen e s ()+exitCode = do mov esp ebp+              pop ebp+              ret++variableAddress :: Ptr Int32 -> Char -> Addr+variableAddress env c =+    let ofs = fromEnum c - fromEnum 'a'+        env' = advancePtr env ofs+    in Addr (fromIntegral (ptrToWordPtr env'))
harpy.cabal view
@@ -1,12 +1,13 @@+Cabal-version:  >=1.2 Name:           harpy-Version:        0.2+Version:        0.4 License:        GPL License-file:   COPYING Author:         Dirk Kleeblatt <klee@cs.tu-berlin.de>                 Martin Grabmueller <magr@cs.tu-berlin.de> Maintainer:     klee@cs.tu-berlin.de, magr@cs.tu-berlin.de Homepage:       http://uebb.cs.tu-berlin.de/harpy/-Category:       Code generation+Category:       Code Generation Synopsis:       Runtime code generation for x86 machine code Description:	The package contains the following components: 	.@@ -27,15 +28,35 @@ 	. 	* All the above modules use the code generation monad defined in module 	  "Harpy.CodeGenMonad".+        .+        * The Darcs repo and two tutorials on using Harpy can be found at+          Harpy's homepage: <http://uebb.cs.tu-berlin.de/harpy/> Stability:      Experimental-Build-depends:  base, parsec, mtl, template-haskell-Exposed-Modules:++Extra-source-files: +    NEWS README Makefile+    doc/Makefile doc/tutorial.lhs doc/larger-tutorial.lhs+    examples/evaluator/ArithTypes.hs examples/evaluator/ArithParser.hs+    examples/evaluator/Evaluator.hs++Flag small_base+  Description: Choose the new smaller, split-up base package.++Library+  if flag(small_base)+    Build-depends:  base >= 3,parsec,mtl,template-haskell,pretty,containers,array+  else+    Build-Depends: base < 3,parsec,mtl,template-haskell+  Exposed-Modules:+    Harpy,     Harpy.X86CodeGen,     Harpy.X86Assembler,     Harpy.CodeGenMonad,     Harpy.Call,     Harpy.X86Disassembler,     Harpy.X86CGCombinators-Extensions:     ForeignFunctionInterface, MultiParamTypeClasses, -	TemplateHaskell, CPP-ghc-options:	-O+  Extensions: +    ForeignFunctionInterface, MultiParamTypeClasses, +    TemplateHaskell, CPP, FlexibleContexts, FlexibleInstances,+    RankNTypes+  Ghc-options: -O2